chore: 规范 module 名称
This commit is contained in:
19
package/layer/.gitignore
vendored
Normal file
19
package/layer/.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
example/dist/
|
||||
lib/
|
||||
/types/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
56
package/layer/package.json
Normal file
56
package/layer/package.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "@layui/layer-vue",
|
||||
"version": "1.3.11",
|
||||
"description": "a component library for Vue 3 base on layui-vue",
|
||||
"homepage": "https://gitee.com/layui-vue/layui-vue/blob/master/README.md",
|
||||
"module": "lib/layer-vue.es.js",
|
||||
"main": "lib/layer-vue.umd.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./lib/layer-vue.es.js",
|
||||
"require": "./lib/layer-vue.umd.js"
|
||||
},
|
||||
"./lib/": "./lib/"
|
||||
},
|
||||
"types": "types/index.d.ts",
|
||||
"style": "lib/index.css",
|
||||
"scripts": {
|
||||
"build": "vite build --emptyOutDir && npm run build:types",
|
||||
"build:types": "rimraf types && tsc -d"
|
||||
},
|
||||
"keywords": [
|
||||
"layui-vue",
|
||||
"layui",
|
||||
"vue"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.8",
|
||||
"@babel/preset-env": "^7.15.8",
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@types/markdown-it": "^12.2.3",
|
||||
"@types/markdown-it-container": "^2.0.4",
|
||||
"@types/node": "^16.11.9",
|
||||
"@vitejs/plugin-vue": "^2.3.1",
|
||||
"@vue/compiler-sfc": "^3.2.31",
|
||||
"@vue/server-renderer": "^3.2.31",
|
||||
"escape-html": "^1.0.3",
|
||||
"less": "^4.1.2",
|
||||
"markdown-it-container": "^3.0.0",
|
||||
"prismjs": "^1.25.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^2.70.1",
|
||||
"typescript": "^4.6.3",
|
||||
"vite": "2.9.1",
|
||||
"vite-plugin-md": "^0.12.4"
|
||||
},
|
||||
"files": [
|
||||
"lib",
|
||||
"types"
|
||||
],
|
||||
"browserslist": [
|
||||
"current node",
|
||||
"last 2 versions and > 2%",
|
||||
"ie > 10"
|
||||
]
|
||||
}
|
||||
0
package/layer/script/.keep
Normal file
0
package/layer/script/.keep
Normal file
25
package/layer/shims-vue.d.ts
vendored
Normal file
25
package/layer/shims-vue.d.ts
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
declare module "*.vue" {
|
||||
import { DefineComponent } from "vue";
|
||||
const comp: DefineComponent;
|
||||
export default comp;
|
||||
}
|
||||
|
||||
declare module "*.md" {
|
||||
import { DefineComponent } from "vue";
|
||||
const comp: DefineComponent;
|
||||
export default comp;
|
||||
}
|
||||
|
||||
declare module "prismjs";
|
||||
declare module "prismjs/components/index";
|
||||
declare module "escape-html";
|
||||
|
||||
interface ImportMeta {
|
||||
env: {
|
||||
MODE: string;
|
||||
BASE_URL: string;
|
||||
PROD: boolean;
|
||||
DEV: boolean;
|
||||
SSR: boolean;
|
||||
};
|
||||
}
|
||||
23
package/layer/src/component/CloseBtn.vue
Normal file
23
package/layer/src/component/CloseBtn.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "CloseBtn",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineEmits } from "vue";
|
||||
|
||||
const emit = defineEmits(["closeHandle"]);
|
||||
|
||||
const closeHandle = () => {
|
||||
emit("closeHandle");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
class="layui-layer-ico layui-layer-close layui-layer-close1"
|
||||
href="javascript:;"
|
||||
@click="closeHandle"
|
||||
></a>
|
||||
</template>
|
||||
23
package/layer/src/component/Iframe.vue
Normal file
23
package/layer/src/component/Iframe.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Iframe",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
export interface IframeProps {
|
||||
src: string;
|
||||
}
|
||||
|
||||
const props = defineProps<IframeProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<iframe
|
||||
scrolling="auto"
|
||||
class="layui-layer-iframe"
|
||||
allowtransparency="true"
|
||||
frameborder="0"
|
||||
:src="src"
|
||||
></iframe>
|
||||
</template>
|
||||
9
package/layer/src/component/Resize.vue
Normal file
9
package/layer/src/component/Resize.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Resize",
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="layui-layer-resize"></span>
|
||||
</template>
|
||||
39
package/layer/src/component/Shade.vue
Normal file
39
package/layer/src/component/Shade.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Shade",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, defineEmits } from "vue";
|
||||
|
||||
const emit = defineEmits(["shadeClick"]);
|
||||
|
||||
export interface ShadeProps {
|
||||
index: number;
|
||||
opacity: string;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
const props = defineProps<ShadeProps>();
|
||||
|
||||
const styles = computed(() => {
|
||||
return {
|
||||
opacity: props.opacity,
|
||||
zIndex: props.index,
|
||||
};
|
||||
});
|
||||
|
||||
const shadeClick = () => {
|
||||
emit("shadeClick");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="layui-layer-shade"
|
||||
:style="styles"
|
||||
@click="shadeClick"
|
||||
v-if="visible"
|
||||
></div>
|
||||
</template>
|
||||
26
package/layer/src/component/Title.vue
Normal file
26
package/layer/src/component/Title.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "Title",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
export interface HeaderProps {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const renderContent = function (content: any) {
|
||||
if (typeof content === "function") {
|
||||
return content();
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
const props = defineProps<HeaderProps>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layui-layer-title" style="cursor: move">
|
||||
{{ renderContent(title) }}
|
||||
</div>
|
||||
</template>
|
||||
1
package/layer/src/component/index.ts
Normal file
1
package/layer/src/component/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as LayLayer } from "./index.vue"; // layer component
|
||||
610
package/layer/src/component/index.vue
Normal file
610
package/layer/src/component/index.vue
Normal file
@@ -0,0 +1,610 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "LayLayer",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Shade from "./Shade.vue";
|
||||
import Iframe from "./Iframe.vue";
|
||||
import Title from "./Title.vue";
|
||||
import CloseBtn from "./CloseBtn.vue";
|
||||
import Resize from "./Resize.vue";
|
||||
import {
|
||||
Ref,
|
||||
ref,
|
||||
watch,
|
||||
computed,
|
||||
useSlots,
|
||||
VNodeTypes,
|
||||
nextTick,
|
||||
inject,
|
||||
} from "vue";
|
||||
import {
|
||||
nextId,
|
||||
maxArea,
|
||||
maxOffset,
|
||||
getArea,
|
||||
calculateArea,
|
||||
calculateOffset,
|
||||
calculateContent,
|
||||
calculateType,
|
||||
minArea,
|
||||
minOffset,
|
||||
updateMinArrays,
|
||||
getDrawerAnimationClass,
|
||||
calculateDrawerArea,
|
||||
} from "../utils";
|
||||
import useMove from "../composable/useMove";
|
||||
import useResize from "../composable/useResize";
|
||||
import { zIndexKey } from "../tokens";
|
||||
|
||||
const slots = useSlots();
|
||||
const layero = ref<HTMLElement | null>(null);
|
||||
const emit = defineEmits(["close", "update:modelValue"]);
|
||||
|
||||
export interface LayModalProps {
|
||||
title?: string | boolean | Function;
|
||||
icon?: string | number;
|
||||
skin?: string;
|
||||
zIndex?: number | Function;
|
||||
setTop?: boolean;
|
||||
offset?: string[] | string;
|
||||
area?: string[] | "auto";
|
||||
modelValue?: boolean;
|
||||
maxmin?: boolean | string;
|
||||
btn?: Record<string, unknown>[] | false;
|
||||
move?: boolean | string;
|
||||
resize?: boolean | string;
|
||||
type?: 0 | 1 | 2 | 3 | "dialog" | "page" | "iframe" | "loading" | "drawer";
|
||||
content?: string | Function | object | VNodeTypes;
|
||||
isHtmlFragment?: boolean;
|
||||
shade?: boolean | string;
|
||||
shadeClose?: boolean | string;
|
||||
shadeOpacity?: string;
|
||||
closeBtn?: boolean | string;
|
||||
btnAlign?: "l" | "c" | "r";
|
||||
time?: number;
|
||||
load?: number;
|
||||
anim?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||
isOutAnim?: boolean;
|
||||
destroy?: Function;
|
||||
success?: Function;
|
||||
end?: Function;
|
||||
yes?: Function;
|
||||
yesText?: string;
|
||||
isFunction?: boolean;
|
||||
isMessage?: boolean;
|
||||
appContext?: any;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LayModalProps>(), {
|
||||
title: "信息",
|
||||
setTop: false,
|
||||
offset: () => ["50%", "50%"],
|
||||
area: "auto",
|
||||
modelValue: false,
|
||||
maxmin: false,
|
||||
move: true,
|
||||
type: 1,
|
||||
time: 0,
|
||||
shade: true,
|
||||
shadeClose: true,
|
||||
shadeOpacity: "0.1",
|
||||
closeBtn: true,
|
||||
btnAlign: "r",
|
||||
load: 0,
|
||||
anim: 0,
|
||||
resize: false,
|
||||
isHtmlFragment: false,
|
||||
isOutAnim: true,
|
||||
destroy: () => {},
|
||||
success: () => {},
|
||||
end: () => {},
|
||||
yesText: "确定",
|
||||
isFunction: false,
|
||||
isMessage: false,
|
||||
});
|
||||
|
||||
const id: Ref<string> = ref(nextId());
|
||||
const max: Ref<boolean> = ref(false);
|
||||
const min: Ref<boolean> = ref(false);
|
||||
const type: number = calculateType(props.type);
|
||||
const area: Ref<string[]> = ref(
|
||||
calculateArea(props.type, props.area, props.offset)
|
||||
);
|
||||
const offset: Ref<string[]> = ref(
|
||||
calculateOffset(props.offset, area.value, props.type)
|
||||
);
|
||||
const contentHeight = ref(
|
||||
calculateContent(area.value[1], props.btn, type, props.isMessage)
|
||||
);
|
||||
const index: Ref<number | Function> = ref(
|
||||
props.zIndex ?? inject(zIndexKey, 99999)
|
||||
);
|
||||
const visible: Ref<boolean> = ref(false);
|
||||
const first: Ref<boolean> = ref(true);
|
||||
|
||||
const w: Ref<string> = ref(area.value[0]);
|
||||
const h: Ref<string> = ref(area.value[1]);
|
||||
const t: Ref<string> = ref(offset.value[0]);
|
||||
const l: Ref<string> = ref(offset.value[1]);
|
||||
|
||||
const _w: Ref<string> = ref(area.value[0]);
|
||||
const _h: Ref<string> = ref(area.value[0]);
|
||||
const _t: Ref<string> = ref(offset.value[0]);
|
||||
const _l: Ref<string> = ref(offset.value[1]);
|
||||
|
||||
/**
|
||||
* 首次打开
|
||||
* <p>
|
||||
*/
|
||||
const firstOpenDelayCalculation = function () {
|
||||
nextTick(() => {
|
||||
area.value = getArea(layero.value);
|
||||
if (props.type === "drawer") {
|
||||
area.value = calculateDrawerArea(props.offset, props.area);
|
||||
}
|
||||
offset.value = calculateOffset(props.offset, area.value, props.type);
|
||||
|
||||
w.value = area.value[0];
|
||||
h.value = area.value[1];
|
||||
t.value = offset.value[0];
|
||||
l.value = offset.value[1];
|
||||
|
||||
_w.value = area.value[0];
|
||||
_l.value = area.value[1];
|
||||
_t.value = offset.value[0];
|
||||
_l.value = offset.value[1];
|
||||
|
||||
supportMove();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 普通打开
|
||||
* <p>
|
||||
*/
|
||||
const notFirstOpenLayerInit = function () {
|
||||
w.value = _w.value;
|
||||
h.value = _h.value;
|
||||
t.value = _t.value;
|
||||
l.value = _l.value;
|
||||
supportMove();
|
||||
};
|
||||
|
||||
/**
|
||||
* Component 模式, 关闭事件
|
||||
* <p>
|
||||
* 在 Component 模式下, 隐藏前需要恢复正常窗体位置与尺寸, 保存
|
||||
**/
|
||||
const beforeCloseSaveData = function () {
|
||||
if (min.value) minHandle();
|
||||
if (max.value) maxHandle();
|
||||
_w.value = w.value;
|
||||
_h.value = h.value;
|
||||
_t.value = t.value;
|
||||
_l.value = l.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* 弹层最大化
|
||||
* <p>
|
||||
*/
|
||||
const maxHandle = () => {
|
||||
if (max.value) {
|
||||
w.value = _w.value;
|
||||
h.value = _h.value;
|
||||
t.value = _t.value;
|
||||
l.value = _l.value;
|
||||
} else {
|
||||
_t.value = t.value;
|
||||
_l.value = l.value;
|
||||
_w.value = w.value;
|
||||
_h.value = h.value;
|
||||
w.value = maxArea().w;
|
||||
h.value = maxArea().h;
|
||||
t.value = maxOffset().t;
|
||||
l.value = maxOffset().l;
|
||||
}
|
||||
max.value = !max.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* 弹层最小化
|
||||
* <p>
|
||||
*/
|
||||
const minHandle = () => {
|
||||
let left = 180 * updateMinArrays(id.value, !min.value);
|
||||
if (left > document.documentElement.clientWidth - 180) {
|
||||
left = document.documentElement.clientWidth - 180;
|
||||
}
|
||||
if (min.value) {
|
||||
w.value = _w.value;
|
||||
h.value = _h.value;
|
||||
t.value = _t.value;
|
||||
l.value = _l.value;
|
||||
} else {
|
||||
_w.value = w.value;
|
||||
_h.value = h.value;
|
||||
_t.value = t.value;
|
||||
_l.value = l.value;
|
||||
h.value = minArea().h;
|
||||
w.value = minArea().w;
|
||||
t.value = minOffset(left).t;
|
||||
l.value = minOffset(left).l;
|
||||
}
|
||||
min.value = !min.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* 重置弹层
|
||||
* <p>
|
||||
*/
|
||||
const reset = function () {
|
||||
if (!first.value) {
|
||||
min.value = false;
|
||||
max.value = false;
|
||||
w.value = area.value[0];
|
||||
h.value = area.value[1];
|
||||
t.value = offset.value[0];
|
||||
l.value = offset.value[1];
|
||||
_w.value = area.value[0];
|
||||
_h.value = area.value[1];
|
||||
_t.value = offset.value[0];
|
||||
_l.value = offset.value[1];
|
||||
}
|
||||
if (!props.modelValue) {
|
||||
emit("update:modelValue", true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 监听 modalValue 的值
|
||||
* <p>
|
||||
* 只有 Component 模式会触发
|
||||
*/
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => {
|
||||
visible.value = props.modelValue;
|
||||
if (visible.value) {
|
||||
if (first.value) {
|
||||
first.value = false;
|
||||
firstOpenDelayCalculation();
|
||||
} else {
|
||||
notFirstOpenLayerInit();
|
||||
}
|
||||
} else {
|
||||
beforeCloseSaveData();
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
/**
|
||||
* 监听 visible 值
|
||||
* <p>
|
||||
*/
|
||||
watch(
|
||||
() => visible.value,
|
||||
() => {
|
||||
if (visible.value) {
|
||||
if (props.isFunction) {
|
||||
firstOpenDelayCalculation();
|
||||
}
|
||||
props.success();
|
||||
} else {
|
||||
props.end();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 高度监听
|
||||
* <p>
|
||||
*
|
||||
* 在发生拖拽时, 需根据弹出层的外层高度计算 content 高度, 需要
|
||||
* 考虑 btn 操作栏, 计算公式:contentHeight = h - btnHeight
|
||||
*
|
||||
* @param h 弹层高度
|
||||
* @param btn 操作栏
|
||||
* @param type 弹层类型
|
||||
*/
|
||||
watch(
|
||||
() => h.value,
|
||||
() => {
|
||||
contentHeight.value = calculateContent(
|
||||
h.value,
|
||||
props.btn,
|
||||
type,
|
||||
props.isMessage
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* 弹层类型
|
||||
*
|
||||
* @param type 类型
|
||||
* @param isMessage 是消息
|
||||
* @param icon 图标类型
|
||||
*/
|
||||
const boxClasses = computed(() => {
|
||||
return [
|
||||
type === 0 ? "layui-layer-dialog" : "",
|
||||
type === 1 ? "layui-layer-page" : "",
|
||||
type === 2 ? "layui-layer-iframe" : "",
|
||||
type === 3 ? "layui-layer-loading" : "",
|
||||
props.isMessage ? "layui-layer-msg" : "",
|
||||
props.isMessage && !props.icon ? "layui-layer-hui" : "",
|
||||
props.skin,
|
||||
];
|
||||
});
|
||||
|
||||
/**
|
||||
* 拖拽拉伸
|
||||
* <p>
|
||||
*/
|
||||
const supportMove = function () {
|
||||
if (props.move && props.type != "drawer") {
|
||||
nextTick(() => {
|
||||
// @ts-ignore 拖拽
|
||||
useMove(layero.value, (left, top) => {
|
||||
l.value = left;
|
||||
t.value = top;
|
||||
});
|
||||
// @ts-ignore 拉伸
|
||||
useResize(layero.value, (width, height) => {
|
||||
h.value = height;
|
||||
w.value = width;
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 弹层样式
|
||||
* <p>
|
||||
*/
|
||||
const styles = computed(() => {
|
||||
return {
|
||||
top: t.value,
|
||||
left: l.value,
|
||||
width: w.value,
|
||||
height: h.value,
|
||||
zIndex: index.value,
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 弹层内容
|
||||
* <p>
|
||||
* @param type 类型
|
||||
* @param load 加载动画
|
||||
* @param icon 图标
|
||||
*/
|
||||
const contentClasses = computed(() => {
|
||||
return [
|
||||
type === 3 ? `layui-layer-loading${props.load}` : "",
|
||||
props.icon ? "layui-layer-padding" : "",
|
||||
];
|
||||
});
|
||||
|
||||
/**
|
||||
* 关闭操作
|
||||
* <p>
|
||||
* @param null
|
||||
*/
|
||||
const closeHandle = () => {
|
||||
emit("close");
|
||||
emit("update:modelValue", false);
|
||||
props.destroy();
|
||||
};
|
||||
|
||||
/**
|
||||
* 确定操作
|
||||
* <p>
|
||||
* @param null
|
||||
*/
|
||||
const yesHandle = () => {
|
||||
if (props.yes != undefined) props.yes();
|
||||
else closeHandle();
|
||||
};
|
||||
|
||||
/**
|
||||
* 遮盖层点击
|
||||
* <p>
|
||||
* @param null
|
||||
*/
|
||||
const shadeHandle = () => {
|
||||
if (props.shadeClose) closeHandle();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取内容
|
||||
* <p>
|
||||
* @param content 文本 / 方法
|
||||
*/
|
||||
const renderContent = function (content: any) {
|
||||
if (content instanceof Function) {
|
||||
return content();
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
/**
|
||||
* 弹层图标
|
||||
* <p>
|
||||
* @param icon 图标
|
||||
*/
|
||||
const iconClass = computed(() => {
|
||||
return ["layui-layer-ico", `layui-layer-ico${props.icon}`];
|
||||
});
|
||||
|
||||
/**
|
||||
* 入场动画
|
||||
* <p>
|
||||
* @param type 类型
|
||||
* @param anim 入场动画
|
||||
*/
|
||||
const enterActiveClass = computed(() => {
|
||||
if (props.type === "drawer") {
|
||||
return getDrawerAnimationClass(props.offset);
|
||||
}
|
||||
return `layer-anim layer-anim-0${props.anim}`;
|
||||
});
|
||||
|
||||
/**
|
||||
* 离场动画
|
||||
* <p>
|
||||
* @param type 类型
|
||||
* @param isOutAnim 离场动画
|
||||
*/
|
||||
const leaveActiveClass = computed(() => {
|
||||
if (props.type === "drawer") {
|
||||
return getDrawerAnimationClass(props.offset, true);
|
||||
}
|
||||
return props.isOutAnim ? `layer-anim-close` : "";
|
||||
});
|
||||
|
||||
/**
|
||||
* 打卡弹层
|
||||
* <p>
|
||||
*/
|
||||
const open = () => {
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭弹层
|
||||
* <p>
|
||||
*/
|
||||
const close = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示遮盖
|
||||
* <p>
|
||||
* @param visible 弹层状态
|
||||
* @param shade 开启遮盖
|
||||
* @param min 最小化
|
||||
*/
|
||||
const shadeVisible = computed(() => {
|
||||
return visible.value && props.shade && !min.value;
|
||||
});
|
||||
|
||||
/**
|
||||
* 拉伸支持
|
||||
* <p>
|
||||
* @param resize 拉伸
|
||||
* @param max 最大化
|
||||
* @param min 最小化
|
||||
*/
|
||||
const showResize = computed(() => {
|
||||
return props.resize && !max.value && !min.value;
|
||||
});
|
||||
|
||||
/**
|
||||
* 显示标题
|
||||
* <p>
|
||||
* @param title 标题
|
||||
* @param type 类型
|
||||
*/
|
||||
const showTitle = computed(() => {
|
||||
return props.title && props.type != 3;
|
||||
});
|
||||
|
||||
defineExpose({ reset, open, close });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<!-- 遮盖层 -->
|
||||
<Shade
|
||||
:index="index"
|
||||
:visible="shadeVisible"
|
||||
:opacity="shadeOpacity"
|
||||
@shadeClick="shadeHandle"
|
||||
></Shade>
|
||||
<!-- 动画容器 -->
|
||||
<transition
|
||||
:enter-active-class="enterActiveClass"
|
||||
:leave-active-class="leaveActiveClass"
|
||||
>
|
||||
<!-- 弹出层 -->
|
||||
<div
|
||||
ref="layero"
|
||||
class="layui-layer layui-layer-border"
|
||||
:class="boxClasses"
|
||||
:style="styles"
|
||||
v-if="visible"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<Title v-if="showTitle" :title="title"></Title>
|
||||
<!-- 内容 -->
|
||||
<div
|
||||
class="layui-layer-content"
|
||||
:style="{ height: contentHeight }"
|
||||
:class="contentClasses"
|
||||
>
|
||||
<template v-if="type === 0 || type === 1">
|
||||
<i v-if="icon" :class="iconClass"></i>
|
||||
<slot v-if="slots.default"></slot>
|
||||
<template v-else>
|
||||
<template v-if="isHtmlFragment">
|
||||
<span v-html="renderContent(props.content)"></span>
|
||||
</template>
|
||||
<template v-else>{{ renderContent(props.content) }}</template>
|
||||
</template>
|
||||
</template>
|
||||
<Iframe v-if="type === 2" :src="props.content"></Iframe>
|
||||
</div>
|
||||
<!-- 工具栏 -->
|
||||
<span class="layui-layer-setwin" v-if="type != 3">
|
||||
<a
|
||||
v-if="maxmin && !max"
|
||||
class="layui-layer-min"
|
||||
:class="[min ? 'layui-layer-ico layui-layer-maxmin' : '']"
|
||||
href="javascript:;"
|
||||
@click="minHandle"
|
||||
>
|
||||
<cite v-if="!min"></cite>
|
||||
</a>
|
||||
<a
|
||||
v-if="maxmin && !min"
|
||||
class="layui-layer-ico layui-layer-max"
|
||||
:class="[max ? 'layui-layer-maxmin' : '']"
|
||||
href="javascript:;"
|
||||
@click="maxHandle"
|
||||
></a>
|
||||
<CloseBtn v-if="closeBtn" @closeHandle="closeHandle"></CloseBtn>
|
||||
</span>
|
||||
<!-- 操作栏 -->
|
||||
<div
|
||||
v-if="((btn && btn.length > 0) || type === 0) && !isMessage"
|
||||
class="layui-layer-btn"
|
||||
:class="[`layui-layer-btn-${btnAlign}`]"
|
||||
>
|
||||
<template v-if="btn && btn.length > 0">
|
||||
<template v-for="(b, index) in btn" :key="index">
|
||||
<a
|
||||
:class="[`layui-layer-btn${index}`]"
|
||||
@click="b.callback(props.domId)"
|
||||
>{{ b.text }}</a
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<template v-if="type === 0">
|
||||
<a class="layui-layer-btn0" @click="yesHandle()">{{ yesText }}</a>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 辅助栏 -->
|
||||
<Resize v-if="showResize"></Resize>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
52
package/layer/src/composable/useMove.ts
Normal file
52
package/layer/src/composable/useMove.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
const useMove = function (el: HTMLElement, callback: Function) {
|
||||
el.style.position = "fixed";
|
||||
let offsetX: number;
|
||||
let offsetY: number;
|
||||
if (el != null) {
|
||||
el.addEventListener("mousedown", function (event: any) {
|
||||
if (event.path[0].className === "layui-layer-title") {
|
||||
if (event.button == 0 && el != null) {
|
||||
const lexObj: any = getComputedStyle(el);
|
||||
offsetX =
|
||||
event.pageX - el.offsetLeft + parseInt(lexObj["margin-left"]);
|
||||
offsetY =
|
||||
event.pageY - el.offsetTop + parseInt(lexObj["margin-right"]);
|
||||
const move = function (event: any) {
|
||||
if (el != null) {
|
||||
let x = event.pageX - offsetX;
|
||||
let y = event.pageY - offsetY;
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
} else if (
|
||||
x >
|
||||
document.documentElement.clientWidth - el.offsetWidth
|
||||
) {
|
||||
x = document.documentElement.clientWidth - el.offsetWidth;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
} else if (
|
||||
y >
|
||||
document.documentElement.clientHeight - el.offsetHeight
|
||||
) {
|
||||
y = document.documentElement.clientHeight - el.offsetHeight;
|
||||
}
|
||||
el.style.left = `${x}px`;
|
||||
el.style.top = `${y}px`;
|
||||
callback(el.style.left, el.style.top);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
document.addEventListener("mousemove", move);
|
||||
const stop = function () {
|
||||
document.removeEventListener("mousemove", move);
|
||||
document.removeEventListener("mouseup", stop);
|
||||
};
|
||||
document.addEventListener("mouseup", stop);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
export default useMove;
|
||||
34
package/layer/src/composable/useResize.ts
Normal file
34
package/layer/src/composable/useResize.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
const useMove = function (el: HTMLElement, callback: Function) {
|
||||
if (el != null) {
|
||||
el.addEventListener("mousedown", function (event: any) {
|
||||
if (event.path[0].className === "layui-layer-resize") {
|
||||
if (event.button == 0 && el != null) {
|
||||
var x = el.offsetLeft;
|
||||
var y = el.offsetTop;
|
||||
const move = function (moveEvent: any) {
|
||||
if (el != null) {
|
||||
var offsetX = moveEvent.clientX;
|
||||
var offsetY = moveEvent.clientY;
|
||||
var w = offsetX - x;
|
||||
var h = offsetY - y;
|
||||
w < 260 && (w = 260);
|
||||
h < 115 && (h = 115);
|
||||
el.style.width = `${w}px`;
|
||||
el.style.height = `${h}px`;
|
||||
callback(el.style.width, el.style.height);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
document.addEventListener("mousemove", move);
|
||||
const stop = function () {
|
||||
document.removeEventListener("mousemove", move);
|
||||
document.removeEventListener("mouseup", stop);
|
||||
};
|
||||
document.addEventListener("mouseup", stop);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
export default useMove;
|
||||
215
package/layer/src/index.ts
Normal file
215
package/layer/src/index.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
import { render, h, isVNode, getCurrentInstance, AppContext, App } from "vue";
|
||||
import LayLayer from "./component/index.vue";
|
||||
import { InstallOptions } from "./types";
|
||||
import { zIndexKey } from "./tokens";
|
||||
import { nextId } from "./utils";
|
||||
|
||||
// 实例队列
|
||||
const layerInstance: any = [];
|
||||
|
||||
// 新增实例
|
||||
const addInstance = (instance: any) => {
|
||||
layerInstance.push(instance);
|
||||
};
|
||||
|
||||
// 删除实例
|
||||
const delInstance = (id: any) => {
|
||||
layerInstance.forEach((item: any, index: number) => {
|
||||
if (item.modalContainer.id === id) {
|
||||
// 删除元素
|
||||
layerInstance.splice(index, 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 清空实例
|
||||
const cleanInstance = () => {
|
||||
layerInstance.splice(0, layerInstance.length);
|
||||
};
|
||||
|
||||
// 是否存在
|
||||
const isExist = (id: any) => {
|
||||
let b = false;
|
||||
layerInstance.forEach((item: any, index: number) => {
|
||||
if (item.modalContainer.id === id) {
|
||||
b = true;
|
||||
}
|
||||
});
|
||||
return b;
|
||||
};
|
||||
|
||||
// 聚合 modal 配置
|
||||
const mergeOption = (option: any, defaultOption: any) => {
|
||||
if (option) defaultOption = Object.assign(defaultOption, option);
|
||||
return defaultOption;
|
||||
};
|
||||
|
||||
// 创建 modal 容器
|
||||
const createContainer = () => {
|
||||
const modalContainer = document.createElement("div");
|
||||
modalContainer.id = nextId();
|
||||
document.body.appendChild(modalContainer);
|
||||
return modalContainer;
|
||||
};
|
||||
|
||||
// modal 子 VNode
|
||||
const modalChildrenVNode = (content: any) => {
|
||||
if (typeof content === "function") {
|
||||
return isVNode(content()) ? { default: () => content() } : undefined;
|
||||
}
|
||||
return isVNode(content) ? { default: () => content } : undefined;
|
||||
};
|
||||
|
||||
const layer = {
|
||||
// 上下文
|
||||
_context: <AppContext | null>null,
|
||||
|
||||
// 页面
|
||||
open: (option: any, callback: Function) => {
|
||||
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 = {
|
||||
type: 0,
|
||||
title: false,
|
||||
content: message,
|
||||
closeBtn: false,
|
||||
shadeClose: false,
|
||||
isMessage: true,
|
||||
shade: false,
|
||||
time: 1000,
|
||||
btn: false,
|
||||
};
|
||||
return layer.create(option, defaultOption, callback);
|
||||
},
|
||||
// 加载
|
||||
load: (load: number, option: any, callback: Function) => {
|
||||
let defaultOption = {
|
||||
type: 3,
|
||||
load: load,
|
||||
anim: 5,
|
||||
isOutAnim: false,
|
||||
shadeClose: false,
|
||||
};
|
||||
return layer.create(option, defaultOption, callback);
|
||||
},
|
||||
// 确认
|
||||
confirm: (msg: string, option: any, callback: Function) => {
|
||||
let defaultOption = {
|
||||
type: 0,
|
||||
content: msg,
|
||||
shadeClose: false,
|
||||
};
|
||||
return layer.create(option, defaultOption, callback);
|
||||
},
|
||||
// 创建弹出层
|
||||
create: (option: any, defaultOption: any, callback: Function) => {
|
||||
// 销毁定时
|
||||
let timer: NodeJS.Timeout;
|
||||
// 聚合配置 Opt
|
||||
const options = mergeOption(option, defaultOption);
|
||||
// 创建容器 Dom
|
||||
const modalContainer = createContainer();
|
||||
options.id = modalContainer;
|
||||
// 创建虚拟 Dom
|
||||
const modalInstance = h(
|
||||
LayLayer,
|
||||
{
|
||||
...options,
|
||||
isFunction: true,
|
||||
destroy() {
|
||||
clearTimeout(timer);
|
||||
modalInstance.component?.exposed?.close();
|
||||
setTimeout(() => {
|
||||
render(null, modalContainer);
|
||||
// 清空 dom
|
||||
if (document.body.contains(modalContainer)) {
|
||||
document.body.removeChild(modalContainer);
|
||||
}
|
||||
}, 2000);
|
||||
delInstance(modalContainer.id);
|
||||
},
|
||||
},
|
||||
modalChildrenVNode(options.content)
|
||||
);
|
||||
modalInstance.appContext = options.appContext || layer._context;
|
||||
// 将虚拟 dom 渲染到 dom 容器
|
||||
render(modalInstance, modalContainer);
|
||||
// 调用 open 函数
|
||||
modalInstance.component?.exposed?.open();
|
||||
// 延时 time 销毁
|
||||
if (defaultOption && defaultOption.time != undefined) {
|
||||
timer = setTimeout(() => {
|
||||
modalInstance.component?.exposed?.close();
|
||||
if (callback) callback(modalContainer.id);
|
||||
setTimeout(() => {
|
||||
render(null, modalContainer);
|
||||
if (document.body.contains(modalContainer)) {
|
||||
document.body.removeChild(modalContainer);
|
||||
}
|
||||
}, 2000);
|
||||
// 销毁实例
|
||||
delInstance(modalContainer.id);
|
||||
}, defaultOption.time);
|
||||
}
|
||||
// 维护实例
|
||||
addInstance({ modalContainer, modalInstance });
|
||||
// 返回实例
|
||||
return { modalContainer, modalInstance };
|
||||
},
|
||||
// 关闭弹出层
|
||||
close: (instance: any) => {
|
||||
if (instance != null && isExist(instance.modalContainer.id)) {
|
||||
instance.modalInstance.component?.exposed?.close();
|
||||
setTimeout(() => {
|
||||
render(null, instance.modalContainer);
|
||||
if (document.body.contains(instance.modalContainer))
|
||||
document.body.removeChild(instance.modalContainer);
|
||||
}, 2000);
|
||||
}
|
||||
// 销毁实例
|
||||
delInstance(instance.modalContainer.id);
|
||||
},
|
||||
// 关闭所有弹出层
|
||||
closeAll: () => {
|
||||
layerInstance.forEach((item: any) => {
|
||||
item.modalInstance.component?.exposed?.close();
|
||||
setTimeout(() => {
|
||||
render(null, item.modalContainer);
|
||||
if (document.body.contains(item.modalContainer))
|
||||
document.body.removeChild(item.modalContainer);
|
||||
}, 2000);
|
||||
});
|
||||
// 清空实例
|
||||
cleanInstance();
|
||||
},
|
||||
// 重置位置
|
||||
reset: (instance: any) => {
|
||||
instance.modalInstance.component?.exposed?.reset();
|
||||
},
|
||||
};
|
||||
|
||||
// 全局安装
|
||||
const install = (app: App, options?: InstallOptions): void => {
|
||||
layer._context = app._context;
|
||||
app.component(LayLayer.name, LayLayer);
|
||||
app.config.globalProperties.$layer = layer;
|
||||
if (options) {
|
||||
app.provide(zIndexKey, options.zIndex);
|
||||
}
|
||||
};
|
||||
|
||||
export { layer, LayLayer };
|
||||
|
||||
export default { install };
|
||||
|
||||
import "./theme/index.css";
|
||||
BIN
package/layer/src/theme/icon-ext.png
Normal file
BIN
package/layer/src/theme/icon-ext.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
BIN
package/layer/src/theme/icon.png
Normal file
BIN
package/layer/src/theme/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
1251
package/layer/src/theme/index.css
Normal file
1251
package/layer/src/theme/index.css
Normal file
File diff suppressed because it is too large
Load Diff
BIN
package/layer/src/theme/loading-0.gif
Normal file
BIN
package/layer/src/theme/loading-0.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
BIN
package/layer/src/theme/loading-1.gif
Normal file
BIN
package/layer/src/theme/loading-1.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 701 B |
BIN
package/layer/src/theme/loading-2.gif
Normal file
BIN
package/layer/src/theme/loading-2.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
1
package/layer/src/tokens/index.ts
Normal file
1
package/layer/src/tokens/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const zIndexKey = Symbol("zIndex");
|
||||
3
package/layer/src/types/index.ts
Normal file
3
package/layer/src/types/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export type StringObject = Record<string, unknown>;
|
||||
|
||||
export interface InstallOptions extends StringObject {}
|
||||
235
package/layer/src/utils/index.ts
Normal file
235
package/layer/src/utils/index.ts
Normal file
@@ -0,0 +1,235 @@
|
||||
// 随机数
|
||||
export function nextId() {
|
||||
var s: any = [];
|
||||
var hexDigits = "0123456789abcdef";
|
||||
for (var i = 0; i < 36; i++) {
|
||||
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
|
||||
}
|
||||
s[14] = "4";
|
||||
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
|
||||
s[8] = s[13] = s[18] = s[23] = "-";
|
||||
var uuid = s.join("");
|
||||
return uuid;
|
||||
}
|
||||
|
||||
export function calculateMinArea(minArea: any) {
|
||||
if (!minArea) {
|
||||
return ["120px", "100px"];
|
||||
}
|
||||
if (typeof minArea == "string") {
|
||||
return [minArea];
|
||||
}
|
||||
return [minArea];
|
||||
}
|
||||
|
||||
export function calculateArea(type: any, area: any, offset: any) {
|
||||
return type != "drawer"
|
||||
? calculateBaseArea(area)
|
||||
: calculateDrawerArea(offset, area);
|
||||
}
|
||||
|
||||
// 计算宽高
|
||||
// @param area
|
||||
// @param type
|
||||
// @return 正确宽高
|
||||
export function calculateBaseArea(area: any) {
|
||||
if (area === "auto") {
|
||||
return [];
|
||||
}
|
||||
// @ts-ignore
|
||||
if (typeof area == "string") {
|
||||
return [area];
|
||||
}
|
||||
return [...area];
|
||||
}
|
||||
|
||||
// 抽屉宽/高
|
||||
export function calculateDrawerArea(
|
||||
offset: any,
|
||||
drawerArea: string[] | string = "30%"
|
||||
) {
|
||||
if (drawerArea instanceof Array) {
|
||||
return drawerArea;
|
||||
}
|
||||
if (drawerArea === "auto") {
|
||||
drawerArea = "30%";
|
||||
}
|
||||
if (offset === "l" || offset === "r") {
|
||||
return [drawerArea, "100%"];
|
||||
} else if (offset === "t" || offset === "b") {
|
||||
return ["100%", drawerArea];
|
||||
}
|
||||
return [drawerArea, "100%"];
|
||||
}
|
||||
|
||||
// 计算偏移
|
||||
// @param offset
|
||||
// @param domSize
|
||||
// @return 正确位置
|
||||
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%";
|
||||
l = "50%";
|
||||
}
|
||||
// 预备处理
|
||||
if (arr.indexOf(offset) != -1 || t.indexOf("%") > -1)
|
||||
t = "calc(" + t + " - (" + (area === "auto" ? "100px" : area[1]) + "/2 ))";
|
||||
if (arr.indexOf(offset) != -1 || l.indexOf("%") > -1)
|
||||
l = "calc(" + l + " - (" + (area === "auto" ? "100px" : area[0]) + "/2 ))";
|
||||
// 关键字处理
|
||||
if (offset === "t") t = "0px";
|
||||
else if (offset === "r") l = "calc(100% - " + area[0] + ")";
|
||||
else if (offset === "b") t = "calc(100% - " + area[1] + ")";
|
||||
else if (offset === "l") l = "0px";
|
||||
else if (offset === "lt") {
|
||||
t = "0px";
|
||||
l = "0px";
|
||||
} else if (offset === "lb") {
|
||||
t = "calc(100% - " + area[1] + ")";
|
||||
l = "0px";
|
||||
} else if (offset === "rt") {
|
||||
t = "0px";
|
||||
l = "calc(100% - " + area[0] + ")";
|
||||
} else if (offset === "rb") {
|
||||
t = "calc(100% - " + area[1] + ")";
|
||||
l = "calc(100% - " + area[0] + ")";
|
||||
}
|
||||
|
||||
// 返回位置
|
||||
return [t, l];
|
||||
}
|
||||
|
||||
// 窗体类型
|
||||
export function calculateType(modalType: number | string) {
|
||||
if (modalType === "dialog" || modalType === 0 || modalType === "0") {
|
||||
return 0;
|
||||
} else if (
|
||||
modalType === "page" ||
|
||||
modalType === "drawer" ||
|
||||
modalType === 1 ||
|
||||
modalType === "1"
|
||||
) {
|
||||
return 1;
|
||||
} else if (modalType === "iframe" || modalType === 2 || modalType === "2") {
|
||||
return 2;
|
||||
} else if (modalType === "loading" || modalType === 3 || modalType === "3") {
|
||||
return 3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 计算高度
|
||||
// @param height 高度
|
||||
// @param btn 操作集合
|
||||
export function calculateContent(
|
||||
height: any,
|
||||
btn: any,
|
||||
type: any,
|
||||
isMessage?: boolean
|
||||
) {
|
||||
if (height && height.indexOf("%") != -1) {
|
||||
height = "100%";
|
||||
}
|
||||
if (btn && btn.length > 0) {
|
||||
if (type === 0) {
|
||||
return "calc(" + height + " - 137px)";
|
||||
}
|
||||
if (type === 1) {
|
||||
return "calc(" + height + " - 102px)";
|
||||
}
|
||||
if (type === 2) {
|
||||
return "calc(" + height + " - 102px)";
|
||||
}
|
||||
} else {
|
||||
if (type === 0) {
|
||||
return isMessage ? height : "calc(" + height + " - 137px)";
|
||||
}
|
||||
if (type === 1) {
|
||||
return "calc(" + height + " - 51px)";
|
||||
}
|
||||
if (type === 2) {
|
||||
return "calc(" + height + " - 51px)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 尺寸常量
|
||||
export function maxArea() {
|
||||
return { w: "100%", h: "100%" };
|
||||
}
|
||||
|
||||
// 初始位置
|
||||
export function maxOffset() {
|
||||
return { t: "0px", l: "0px" };
|
||||
}
|
||||
|
||||
// 最小化尺寸
|
||||
export function minArea() {
|
||||
return { w: "180px", h: "51px" };
|
||||
}
|
||||
|
||||
// 最小化位置
|
||||
export function minOffset(left: any) {
|
||||
return { t: "calc(100% - 51px)", l: left + "px" };
|
||||
}
|
||||
|
||||
// 元素位置
|
||||
// @param x 横坐标
|
||||
// @param y 纵坐标
|
||||
export function getPosition(dom: any) {
|
||||
return { x: dom?.style.left, y: dom?.style.top };
|
||||
}
|
||||
|
||||
// 元素宽高
|
||||
export function getArea(dom: any) {
|
||||
// @ts-ignore
|
||||
let width = getComputedStyle(dom, null).width;
|
||||
// @ts-ignore
|
||||
let height = getComputedStyle(dom, null).height;
|
||||
return [width, height];
|
||||
}
|
||||
|
||||
// 最小化的队列
|
||||
let minArrays: Array<String> = [];
|
||||
|
||||
// 更新最小化队列
|
||||
export function updateMinArrays(id: string, state: Boolean) {
|
||||
var i = 0;
|
||||
if (state) {
|
||||
const index = minArrays.findIndex((v) => v === undefined);
|
||||
if (index === -1) {
|
||||
minArrays.push(id);
|
||||
i = minArrays.length - 1;
|
||||
} else {
|
||||
minArrays[index] = id;
|
||||
i = index;
|
||||
}
|
||||
} else {
|
||||
delete minArrays[minArrays.findIndex((v) => v == id)];
|
||||
i = -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
// 抽屉动画类
|
||||
export function getDrawerAnimationClass(offset: any, isClose: boolean = false) {
|
||||
const prefix = "layer-drawer-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}`;
|
||||
}
|
||||
18
package/layer/tsconfig.json
Normal file
18
package/layer/tsconfig.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"module": "esnext",
|
||||
"target": "es2015",
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"allowJs": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"esModuleInterop": true,
|
||||
"declarationDir": "types",
|
||||
"lib": ["ESNext","DOM"]
|
||||
},
|
||||
"include": ["src/**/*","shims-vue.d.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
44
package/layer/vite.config.ts
Normal file
44
package/layer/vite.config.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { name } from "./package.json";
|
||||
import babel from "@rollup/plugin-babel";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import path from "path";
|
||||
|
||||
const camelize = (name: string) =>
|
||||
name.replace(/(^|-)(\w)/g, (a, b, c) => c.toUpperCase());
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
"/@src": path.resolve(__dirname, "src"),
|
||||
},
|
||||
},
|
||||
plugins: [vue()],
|
||||
build: {
|
||||
target: "es2015",
|
||||
outDir: path.resolve(__dirname, "lib"),
|
||||
lib: {
|
||||
entry: path.resolve(__dirname, "src/index.ts"),
|
||||
name: camelize(name),
|
||||
},
|
||||
rollupOptions: {
|
||||
output: {
|
||||
exports: "named",
|
||||
globals: (id: string) => {
|
||||
const name = id.replace(/^@/, "").split("/")[0];
|
||||
return camelize(name);
|
||||
},
|
||||
assetFileNames: "index.css",
|
||||
},
|
||||
plugins: [
|
||||
// @ts-ignore
|
||||
babel({
|
||||
exclude: "node_modules/**",
|
||||
extensions: [".js", ".jsx", ".ts", ".tsx", ".vue"],
|
||||
presets: ["@babel/preset-env", "@babel/preset-typescript"],
|
||||
}),
|
||||
],
|
||||
external: ["vue"],
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user