init
This commit is contained in:
@@ -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 };
|
||||
@@ -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 };
|
||||
Binary file not shown.
@@ -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>
|
||||
@@ -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
|
||||
:::
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user