This commit is contained in:
2022-12-09 16:41:41 +08:00
parent c1cce5a7c2
commit ff7aa8774f
2003 changed files with 156639 additions and 140 deletions

View File

@@ -0,0 +1,16 @@
<script lang="ts">
export default {
name: "NextIcon",
};
</script>
<script setup lang="ts">
import LayIcon from "../component/icon/index";
const props = defineProps<{
color?: string;
size?: string;
}>();
</script>
<template>
<lay-icon :color="props.color" :size="props.size" type="layui-icon-next" />
</template>

View File

@@ -0,0 +1,72 @@
import { w as withInstall } from "../badge/index2.js";
import { defineComponent, useSlots, computed, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, renderSlot, createCommentVNode } from "vue";
var index = /* @__PURE__ */ (() => ".layui-line-horizontal{position:relative;clear:both;width:100%;min-width:100%;max-width:100%;margin:var(--layui-line-margin) 0;border-bottom:var(--layui-line-border-width) var(--layui-line-border-style) var(--global-neutral-color-5);border-top-style:none;border-left-style:none;border-right-style:none}.layui-line-horizontal.layui-line-with-text{margin:14px 0}.layui-line-vertical{display:inline-block;min-width:1px;max-width:1px;height:1em;margin:0 var(--layui-line-margin);vertical-align:middle;border-left:var(--layui-line-border-width) var(--layui-line-border-style) var(--global-neutral-color-5);border-top-style:none;border-bottom-style:none;border-right-style:none}.layui-line-text{position:absolute;top:50%;box-sizing:border-box;padding:0 10px;color:currentColor;line-height:2;background-color:#fff;transform:translateY(-50%)}.layui-line-text-center{left:var(--layui-line-text-offset);transform:translate(-50%,-50%)}.layui-line-text-left{left:var(--layui-line-text-offset)}.layui-line-text-right{right:var(--layui-line-text-offset)}\n")();
const __default__ = {
name: "LayLine"
};
const _sfc_main = defineComponent({
...__default__,
props: {
direction: { default: "horizontal" },
contentPosition: { default: "center" },
borderWidth: { default: "1px" },
borderStyle: { default: "solid" },
offset: { default: "25px" },
theme: null,
margin: { default: "8px" }
},
setup(__props) {
var _a;
const props = __props;
const slots = useSlots();
const lineTheme = [
"red",
"orange",
"green",
"cyan",
"blue",
"black",
"gray"
];
const isBuiltInColor = lineTheme.includes((_a = props.theme) != null ? _a : "");
const lineClass = computed(() => [
`layui-line-${props.direction}`,
{
[`layui-border-${props.theme}`]: isBuiltInColor,
[`layui-line-with-text`]: Boolean(slots.default)
}
]);
const lineStyle = computed(() => ({
"border-color": !isBuiltInColor ? props.theme : void 0,
"--layui-line-border-width": props.borderWidth,
"--layui-line-border-style": props.borderStyle,
"--layui-line-margin": props.margin
}));
const lineTextStyle = computed(() => ({
"--layui-line-text-offset": props.contentPosition != "center" ? props.offset : "50%",
transform: calcTranslate()
}));
function calcTranslate() {
if (props.offset.includes("%")) {
return props.contentPosition === "right" ? "translate(50%, -50%)" : "translate(-50%, -50%)";
}
return void 0;
}
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass(unref(lineClass)),
style: normalizeStyle(unref(lineStyle))
}, [
_ctx.$slots.default && __props.direction === "horizontal" ? (openBlock(), createElementBlock("span", {
key: 0,
class: normalizeClass([`layui-line-text layui-line-text-${__props.contentPosition}`]),
style: normalizeStyle(unref(lineTextStyle))
}, [
renderSlot(_ctx.$slots, "default")
], 6)) : createCommentVNode("", true)
], 6);
};
}
});
const component = withInstall(_sfc_main);
export { component as default };

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

View File

@@ -0,0 +1,223 @@
<script lang="ts">
export default {
name: "LayBacktop",
};
</script>
<script lang="ts" setup>
import {
ref,
shallowRef,
withDefaults,
computed,
onMounted,
onBeforeUnmount,
} from "vue";
import { LayIcon } from "@layui/icons-vue";
import "./index.less";
export interface BackTopProps {
target?: string;
showHeight?: number;
disabled?: boolean;
position?: "fixed" | "absolute";
right?: number;
bottom?: number;
size?: "medium" | "small";
bgcolor?: string;
opacity?: number;
color?: string;
borderRadius?: number | string;
circle?: boolean;
icon?: string;
iconSize?: number;
iconColor?: string;
}
const props = withDefaults(defineProps<BackTopProps>(), {
target: "window",
showHeight: 200,
icon: "layui-icon-top",
iconSize: 30,
disabled: false,
circle: false,
});
const emit = defineEmits(["click"]);
const backtopRef = ref<HTMLElement | null>(null);
const scrollTarget = shallowRef<Window | HTMLElement | undefined>(undefined);
let visible = ref(props.showHeight === 0);
const classBacktop = computed(() => {
return {
"layui-backtop-medium": props.size === "medium",
"layui-backtop-small": props.size === "small",
};
});
const borderRadius = computed(() => {
if (props.circle) {
return "50%";
}
return typeof props.borderRadius === "number"
? `${props.borderRadius}px`
: props.borderRadius;
});
const styleBacktop = computed(() => {
return {
position: props.position,
right: `${props.right}px`,
bottom: `${props.bottom}px`,
backgroundColor: props.bgcolor,
opacity: props.opacity,
color: props.color,
borderRadius: borderRadius.value,
};
});
// TODO 待改进
const easeInOut = (value: number): number => {
return value < 0.5 ? 2 * value * value : 1 - 2 * (value - 1) * (value - 1);
};
const scrollToTop = () => {
if (!scrollTarget.value) return;
if (scrollTarget.value instanceof Window) {
window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); // smooth | instant(default)
} else {
const previous: number = Date.now();
const scrollHeight: number = scrollTarget.value.scrollTop;
const animationFunc = () => {
if (!scrollTarget.value || scrollTarget.value instanceof Window) return;
const elapsed = (Date.now() - previous) / 450;
if (elapsed < 1) {
scrollTarget.value.scrollTop = scrollHeight * (1 - easeInOut(elapsed));
window.requestAnimationFrame(animationFunc);
} else {
scrollTarget.value.scrollTop = 0;
}
};
window.requestAnimationFrame(animationFunc);
}
};
const handleScroll = () => {
if (!scrollTarget.value) return;
const scrollTop =
scrollTarget.value instanceof Window
? window.pageYOffset
: scrollTarget.value.scrollTop;
visible.value = scrollTop >= props.showHeight;
};
const handleClick = (event: MouseEvent) => {
if (!props.disabled) {
scrollToTop();
}
emit("click", event);
};
const handlerMousedown = () => {
backtopRef.value!.style.opacity = "1";
};
const handlerMouseup = () => {
backtopRef.value!.style.opacity = "0.95";
};
// 获取滚动目标元素
const getScrollTarget = () => {
if (props.target === "window") {
// @ts-ignore
return getScrollParent(backtopRef.value!, false);
} else {
const targetElement = document.querySelector<HTMLElement>(props.target);
if (!targetElement) {
throw new Error(`target is not existed: ${props.target}`);
}
// 特定容器内部显示
if (props.position === "absolute") {
if (!targetElement.parentElement) {
throw new Error(
`target parent element is not existed: ${props.target}`
);
}
targetElement.parentElement.style.position = "relative";
// backtopRef.value!.style.position = props.position;
}
return targetElement;
}
};
// 获取距离元素最近的可滚动祖先元素
const getScrollParent = (
element: HTMLElement,
includeHidden: boolean
): HTMLElement => {
let style: CSSStyleDeclaration = getComputedStyle(element);
let excludeStaticParent: boolean = style.position === "absolute";
let overflowRegex: RegExp = includeHidden
? /(auto|scroll|hidden)/
: /(auto|scroll)/;
//if (style.position === "fixed") return document.documentElement || document.body || window;
for (let parent: HTMLElement = element; (parent = parent.parentElement!); ) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === "static") {
continue;
}
if (
overflowRegex.test(style.overflow + style.overflowY + style.overflowX)
) {
return parent;
}
}
// @ts-ignore
return window;
};
// 节流
const throttle = (func: Function, wait: number) => {
var timer: any = null;
return (...args: any) => {
if (!timer) {
timer = setTimeout(() => {
timer = null;
func.apply(this, args);
}, wait);
}
};
};
const callback = throttle(handleScroll, 300);
onMounted(() => {
if (!props.target) return;
scrollTarget.value = getScrollTarget();
scrollTarget.value.addEventListener("scroll", callback);
});
onBeforeUnmount(() => {
scrollTarget.value?.removeEventListener("scroll", callback);
});
</script>
<template>
<div
v-show="visible"
ref="backtopRef"
class="layui-backtop"
:class="classBacktop"
:style="{ ...styleBacktop }"
@click.stop="handleClick"
@mousedown="handlerMousedown"
@mouseup="handlerMouseup"
>
<slot>
<lay-icon
:type="props.icon"
:size="`${props.iconSize}px`"
:color="props.iconColor"
/>
</slot>
</div>
</template>

View File

@@ -0,0 +1,163 @@
import { w as withInstall } from "../badge/index2.js";
import { defineComponent, ref, computed, onMounted, onBeforeUnmount, renderSlot } from "vue";
var index = /* @__PURE__ */ (() => ".layui-fullscreen{top:0;left:0;width:100%;height:100%;position:fixed;overflow:auto;z-index:10}\n")();
const __default__ = {
name: "LayFullscreen"
};
const _sfc_main = defineComponent({
...__default__,
props: {
target: null,
immersive: { type: Boolean, default: true },
position: null,
zIndex: null
},
emits: ["fullscreenchange"],
setup(__props, { emit }) {
const props = __props;
const methodMap = [
[
"requestFullscreen",
"exitFullscreen",
"fullscreenElement",
"fullscreenEnabled",
"fullscreenchange",
"fullscreenerror"
],
[
"webkitRequestFullscreen",
"webkitExitFullscreen",
"webkitFullscreenElement",
"webkitFullscreenEnabled",
"webkitfullscreenchange",
"webkitfullscreenerror"
],
[
"webkitRequestFullScreen",
"webkitCancelFullScreen",
"webkitCurrentFullScreenElement",
"webkitCancelFullScreen",
"webkitfullscreenchange",
"webkitfullscreenerror"
],
[
"mozRequestFullScreen",
"mozCancelFullScreen",
"mozFullScreenElement",
"mozFullScreenEnabled",
"mozfullscreenchange",
"mozfullscreenerror"
],
[
"msRequestFullscreen",
"msExitFullscreen",
"msFullscreenElement",
"msFullscreenEnabled",
"MSFullscreenChange",
"MSFullscreenError"
]
];
const defaultElement = document.documentElement;
let targetEl = ref(props.target || defaultElement);
const isFullscreen = ref(false);
let isSupported = false;
const unprefixedMethods = methodMap[0];
const fullscreenAPI = {};
for (const methodList of methodMap) {
if (methodList[1] in document) {
for (const [index2, method] of methodList.entries()) {
fullscreenAPI[unprefixedMethods[index2]] = method;
}
isSupported = true;
break;
}
}
async function enter(targetEl2) {
if (!isSupported)
return;
if (!targetEl2)
targetEl2 = activeEl.value || defaultElement;
let fullscreenEnter = null;
if (props.immersive) {
fullscreenEnter = Promise.resolve(targetEl2[fullscreenAPI.requestFullscreen]());
} else {
styleLayFullscreen(targetEl2, false);
fullscreenEnter = Promise.resolve(targetEl2 == null ? void 0 : targetEl2.classList.add("layui-fullscreen"));
}
return await (fullscreenEnter == null ? void 0 : fullscreenEnter.then(() => {
isFullscreen.value = true;
emit("fullscreenchange", isFullscreen.value);
return !!document.fullscreenElement;
}));
}
async function exit(targetEl2) {
if (!isSupported)
return;
if (!targetEl2)
targetEl2 = activeEl.value || document;
let fullscreenExit = null;
if (props.immersive) {
fullscreenExit = Promise.resolve(document[fullscreenAPI.exitFullscreen]());
} else {
if (targetEl2 instanceof Document)
return;
styleLayFullscreen(targetEl2, true);
fullscreenExit = Promise.resolve(targetEl2 == null ? void 0 : targetEl2.classList.remove("layui-fullscreen"));
}
return await (fullscreenExit == null ? void 0 : fullscreenExit.then(() => {
isFullscreen.value = false;
emit("fullscreenchange", isFullscreen.value);
return !!document.fullscreenElement;
}));
}
async function toggle() {
if (isFullscreen.value) {
await exit(activeEl.value);
} else {
await enter(activeEl.value);
}
}
const styleLayFullscreen = function(el, isRemove = false) {
el.style.position = isRemove ? "" : props.position || "";
el.style.zIndex = isRemove ? "" : props.zIndex || "";
};
const activeEl = computed(() => targetEl.value = props.target);
const onFullscreenchange = function(event) {
if (isFullscreen.value && !document.fullscreenElement) {
if (props.immersive) {
isFullscreen.value = false;
emit("fullscreenchange", isFullscreen.value);
} else if (event.key === "Escape") {
exit(activeEl.value);
}
}
};
const onKeydownF11 = function(event) {
let isRootNodeFullscreen = props.immersive && (!activeEl.value || activeEl.value === defaultElement);
if (event.key === "F11" && isRootNodeFullscreen) {
event.preventDefault();
toggle();
}
};
onMounted(() => {
document.addEventListener(fullscreenAPI.fullscreenchange, onFullscreenchange);
document.addEventListener("keydown", onFullscreenchange);
document.addEventListener("keydown", onKeydownF11);
});
onBeforeUnmount(() => {
document.removeEventListener(fullscreenAPI.fullscreenchange, onFullscreenchange);
document.removeEventListener("keydown", onFullscreenchange);
document.removeEventListener("keydown", onKeydownF11);
});
return (_ctx, _cache) => {
return renderSlot(_ctx.$slots, "default", {
isFullscreen: isFullscreen.value,
enter,
exit,
toggle
});
};
}
});
const component = withInstall(_sfc_main);
export { component as default };