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,119 @@
import { w as withInstall } from "../badge/index2.js";
import { defineComponent, ref, computed, watch, openBlock, createElementBlock, normalizeClass, createElementVNode, Fragment, renderList, unref, normalizeStyle, renderSlot, createTextVNode, toDisplayString, createCommentVNode } from "vue";
var index = /* @__PURE__ */ (() => ".layui-rate,.layui-rate *{display:inline-block;vertical-align:middle}.layui-rate{padding:10px 5px 10px 0;font-size:0}.layui-rate li i.layui-icon{font-size:20px;color:#ffb800;margin-right:5px;transition:all .3s;-webkit-transition:all .3s}.layui-rate li i:hover{cursor:pointer;transform:scale(1.12);-webkit-transform:scale(1.12)}.layui-rate[readonly] li i:hover{cursor:default;transform:scale(1)}.layui-rate-clear-icon{display:inline-block;color:#c6c6c6;padding-top:3px;font-size:18px;vertical-align:middle}.layui-rate-clear-icon:hover{cursor:pointer;color:#ff4949}\n")();
const _hoisted_1 = ["onMousemove", "onClick"];
const _hoisted_2 = {
key: 0,
class: "layui-inline"
};
const __default__ = {
name: "LayRate"
};
const _sfc_main = defineComponent({
...__default__,
props: {
theme: null,
length: { default: 5 },
modelValue: { default: 0 },
readonly: { type: [Boolean, String], default: false },
half: { type: Boolean, default: false },
text: { type: Boolean, default: false },
isBlock: { type: Boolean, default: false },
allowClear: { type: Boolean, default: false },
clearIcon: { default: "layui-icon-close-fill" },
icons: { default: () => [
"layui-icon-rate",
"layui-icon-rate-half",
"layui-icon-rate-solid"
] }
},
emits: ["update:modelValue", "select", "clear"],
setup(__props, { emit }) {
const props = __props;
const currentValue = ref(props.modelValue);
const tempValue = ref(currentValue.value);
const isHalf = computed(() => props.half && Math.round(currentValue.value) !== currentValue.value);
watch(() => props.modelValue, () => {
currentValue.value = props.modelValue;
tempValue.value = props.modelValue;
});
const getValue = function(index2, event) {
if (!props.half) {
return index2;
}
return index2 - (event.offsetX <= event.target.offsetWidth / 2 ? 0.5 : 0);
};
const mousemove = function(index2, event) {
if (props.readonly) {
return false;
}
currentValue.value = getValue(index2, event);
};
const mouseleave = function() {
if (props.readonly) {
return false;
}
currentValue.value = tempValue.value;
};
const action = function(index2, event) {
if (props.readonly) {
return false;
}
currentValue.value = getValue(index2, event);
tempValue.value = currentValue.value;
emit("update:modelValue", currentValue.value);
emit("select", currentValue.value);
};
const showClearIcon = computed(() => !props.readonly && props.allowClear);
const clearRate = function() {
tempValue.value = 0;
currentValue.value = 0;
emit("clear", currentValue.value);
};
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass(__props.isBlock ? "layui-block" : "layui-inline")
}, [
createElementVNode("ul", {
class: "layui-rate",
onMouseleave: mouseleave
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.length, (index2) => {
return openBlock(), createElementBlock("li", {
key: index2,
class: "layui-inline",
onMousemove: ($event) => mousemove(index2, $event),
onClick: ($event) => action(index2, $event)
}, [
index2 <= Math.ceil(currentValue.value) ? (openBlock(), createElementBlock("i", {
key: 0,
class: normalizeClass([
"layui-icon",
`${__props.icons[__props.icons.length - (unref(isHalf) && index2 === Math.ceil(currentValue.value) ? 2 : 1)]}`
]),
style: normalizeStyle({ color: __props.theme })
}, null, 6)) : (openBlock(), createElementBlock("i", {
key: 1,
class: normalizeClass(["layui-icon"].concat(__props.icons[0])),
style: normalizeStyle({ color: __props.theme })
}, null, 6))
], 40, _hoisted_1);
}), 128))
], 32),
__props.text ? (openBlock(), createElementBlock("span", _hoisted_2, [
renderSlot(_ctx.$slots, "default", { value: currentValue.value }, () => [
createTextVNode(toDisplayString(currentValue.value + "\u661F"), 1)
])
])) : createCommentVNode("", true),
unref(showClearIcon) ? (openBlock(), createElementBlock("i", {
key: 1,
class: normalizeClass(["layui-icon", "layui-rate-clear-icon", __props.clearIcon]),
onClick: clearRate,
title: "\u6E05\u9664\u8BC4\u5206"
}, null, 2)) : createCommentVNode("", true)
], 2);
};
}
});
const component = withInstall(_sfc_main);
export { component as default };

View File

@@ -0,0 +1,178 @@
import { w as withInstall } from "../badge/index2.js";
import { defineComponent, ref, shallowRef, computed, onMounted, onBeforeUnmount, withDirectives, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withModifiers, renderSlot, createVNode, vShow } from "vue";
import { _ as _sfc_main$2E } from "../checkbox/index2.js";
var index = /* @__PURE__ */ (() => ".layui-backtop{position:fixed;right:30px;bottom:40px;width:50px;height:50px;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:40px;background-color:#9f9f9f;color:#fff;border-radius:var(--global-border-radius);opacity:.95;z-index:999999}.layui-backtop :hover{opacity:.85}.layui-backtop-medium{width:40px;height:40px;font-size:30px}.layui-backtop-small{width:30px;height:30px;font-size:20px}\n")();
const _hoisted_1 = ["onClick"];
const __default__ = {
name: "LayBacktop"
};
const _sfc_main = defineComponent({
...__default__,
props: {
target: { default: "window" },
showHeight: { default: 200 },
disabled: { type: Boolean, default: false },
position: null,
right: null,
bottom: null,
size: null,
bgcolor: null,
opacity: null,
color: null,
borderRadius: null,
circle: { type: Boolean, default: false },
icon: { default: "layui-icon-top" },
iconSize: { default: 30 },
iconColor: null
},
emits: ["click"],
setup(__props, { emit }) {
const props = __props;
const backtopRef = ref(null);
const scrollTarget = shallowRef(void 0);
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
};
});
const easeInOut = (value) => {
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" });
} else {
const previous = Date.now();
const scrollHeight = 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) => {
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") {
return getScrollParent(backtopRef.value, false);
} else {
const targetElement = document.querySelector(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";
}
return targetElement;
}
};
const getScrollParent = (element, includeHidden) => {
let style = getComputedStyle(element);
let excludeStaticParent = style.position === "absolute";
let overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
for (let parent = element; parent = parent.parentElement; ) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === "static") {
continue;
}
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
return parent;
}
}
return window;
};
const throttle = (func, wait) => {
var timer = null;
return (...args) => {
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(() => {
var _a;
(_a = scrollTarget.value) == null ? void 0 : _a.removeEventListener("scroll", callback);
});
return (_ctx, _cache) => {
return withDirectives((openBlock(), createElementBlock("div", {
ref_key: "backtopRef",
ref: backtopRef,
class: normalizeClass(["layui-backtop", unref(classBacktop)]),
style: normalizeStyle({ ...unref(styleBacktop) }),
onClick: withModifiers(handleClick, ["stop"]),
onMousedown: handlerMousedown,
onMouseup: handlerMouseup
}, [
renderSlot(_ctx.$slots, "default", {}, () => [
createVNode(unref(_sfc_main$2E), {
type: props.icon,
size: `${props.iconSize}px`,
color: props.iconColor
}, null, 8, ["type", "size", "color"])
])
], 46, _hoisted_1)), [
[vShow, unref(visible)]
]);
};
}
});
const component = withInstall(_sfc_main);
export { component as default };

View File

@@ -0,0 +1,16 @@
<script lang="ts">
export default {
name: "VideoIcon",
};
</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-video" />
</template>

View File

@@ -0,0 +1,138 @@
::: anchor
:::
::: title 基本介绍
:::
::: describe 当用户需要频繁返回顶部查看相关内容时。
:::
::: title 基础使用
:::
::: demo 回到顶部组件的默认样式,`lay-backtop` 会自动寻找最近的可滚动祖先元素,也可以使用 `target` 属性指定触发滚动事件的元素,通过滑动来查看页面右下角的正方形按钮。
<template>
<lay-backtop></lay-backtop>
</template>
<script>
</script>
:::
:::title 自定义
::: demo 回到顶部组件可自定义样式限制宽高50px \* 50px`showHeight = 0` 将始终显示,`disabled` 属性禁用返回顶部。查看页面右下角的圆形按钮。
<template>
<!-- 使用默认插槽自定义 -->
<lay-tooltip content="插槽自定义 backtop " position="left">
<lay-backtop @click="handlerClick" :showHeight="0" :bottom="160" bgcolor="#5FB878" circle disabled>
<lay-icon type="layui-icon-dialogue" size="30px"></lay-icon>
</lay-backtop>
</lay-tooltip>
<!-- 使用样式属性自定义 -->
<lay-tooltip content="属性自定义 backtop " position="left">
<lay-backtop :bottom="100" bgcolor="#5FB878" icon="layui-icon-up" circle></lay-backtop>
</lay-tooltip>
</template>
<script>
import { ref } from 'vue'
import { layer } from "@layui/layer-vue"
export default {
setup() {
const handlerClick = () => {
layer.msg("layui-vue", { time: 1000 });
}
return {
handlerClick,
}
}
}
</script>
:::
::: title 挂载容器
:::
::: demo 通过设置 `target` 和 `position="absolute"` 参数,可对特定容器进行返回顶部操作
<template>
<!-- 需要用一个 div 包裹触发滚动事件的目标元素和 lay-backtop 组件 -->
<div class="wrapper" style="width:700px; height:300px;">
<div id="scrollContent" style="overflow-y:auto; overflow-x:auto; width:700px; height:300px;background-color:whitesmoke;">
<lay-panel v-for="(n,index) in 50" :key="n" style="margin:10px;padding:10px;">内容</lay-panel>
</div>
<lay-backtop target="#scrollContent" :showHeight="100" :bottom="30" position="absolute"></lay-backtop>
</div>
</template>
<script>
export default {
setup() {
return {
}
}
}
</script>
:::
::: title 属性
:::
::: table
| 属性 | 描述 | 类型 | 默认值 | 可选值 |
| ------------ | --------------------------------------------- | ---------------- | ---------------- | ------------------------------ |
| target | 可选,触发滚动事件的对象 | string \| Window | `window` | `CSS/Element 选择器` `window` |
| showHeight | 可选,滚动高度达到该值后<br>显示回到顶部按钮 | number | `200` | — |
| disabled | 可选,禁用点击返回顶部 | boolean | `false` | `true` `false` |
| position | 可选,定位方式,特定容器内部<br>需设置为 absolute | string | `fixed` | `absolute` `fixed` |
| right | 可选,按钮距离页面右边距 | number | `30` | — |
| size | 可选,按钮大小 | string | —— | `medium` `small` |
| bottom | 可选,按钮距离页面底部位置 | number | `40` | `40` |
| bgcolor | 可选,背景颜色 | string | `#9F9F9F` | — |
| opacity | 可选,不透明度 | number | `0.95` | `0-1` |
| color | 可选,前景颜色 | string | `#FFFFFF` | — |
| borderRadius | 可选,添加圆角 | number \| string | `2` | e: 2 \| 2px \|50% |
| circle | 可选,使用圆形按钮 | boolean | `false` | `true` `false` |
| icon | 可选,图标类型 | string | `layui-icon-top` | `lay-icon`组件支持的所有类型 |
| iconSize | 可选,图标大小 | number | `30` | `30` |
| iconColor | 可选,图标颜色 | string | `#FFFFFF` | — |
:::
::: title Backtop 事件
:::
::: table
| 事件 | 描述 | 参数 |
| ------ | -------------------------- | -------- |
| click | 点击回到顶部按钮的回调函数 | event |
:::
::: title Backtop 插槽
:::
::: table
| 插槽 | 说明 |
| ------ | ---------- |
| default| 自定义内容 |
:::
::: contributor backtop
:::
::: previousNext backtop
:::

View File

@@ -0,0 +1,13 @@
export declare type SelectValueType = string | string[] | number | number[] | null;
export interface SelectItem {
value?: SelectValueType;
label?: null | string | string[];
disabled?: boolean;
multiple?: boolean;
}
export interface SelectItemHandle {
(selectItem: SelectItem, isChecked?: boolean): void;
}
export interface SelectItemPush {
(selectItem: SelectItem): void;
}