slider
This commit is contained in:
@@ -2844,6 +2844,25 @@ body .layui-table-tips .layui-layer-content {
|
||||
color: #5fb878;
|
||||
}
|
||||
|
||||
.layui-nav .layui-show.layui-anim-upbit .layui-show.layui-anim-upbit {
|
||||
top: 0px;
|
||||
left: 106px;
|
||||
}
|
||||
|
||||
.layui-nav .layui-show.layui-anim-upbit .layui-nav-item {
|
||||
display: block;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.layui-nav .layui-show.layui-anim-upbit .layui-nav-item.layui-this {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
.layui-nav .layui-show.layui-anim-upbit .layui-nav-item.layui-this:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layui-nav {
|
||||
position: relative;
|
||||
padding: 0 20px;
|
||||
@@ -2868,7 +2887,7 @@ body .layui-table-tips .layui-layer-content {
|
||||
|
||||
.layui-nav .layui-nav-item a {
|
||||
display: block;
|
||||
padding: 0 20px;
|
||||
padding: 0 30px;
|
||||
color: #fff;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
-webkit-transition: all 0.3s;
|
||||
@@ -2881,7 +2900,7 @@ body .layui-table-tips .layui-layer-content {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 5px;
|
||||
height: 3px;
|
||||
background-color: #5fb878;
|
||||
transition: all 0.2s;
|
||||
-webkit-transition: all 0.2s;
|
||||
@@ -2917,7 +2936,7 @@ body .layui-table-tips .layui-layer-content {
|
||||
.layui-nav .layui-nav-more {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 3px;
|
||||
right: 8px;
|
||||
left: auto !important;
|
||||
margin-top: 0;
|
||||
font-size: 12.5px !important;
|
||||
@@ -2988,13 +3007,13 @@ body .layui-table-tips .layui-layer-content {
|
||||
.layui-nav-tree .layui-nav-item {
|
||||
display: block;
|
||||
width: 100%;
|
||||
line-height: 40px;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
.layui-nav-tree .layui-nav-item a {
|
||||
position: relative;
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
|
||||
21
src/index.ts
21
src/index.ts
@@ -6,7 +6,7 @@ import "@layui/layer-vue/lib/index.css";
|
||||
import "@layui/icons-vue/lib/index.css";
|
||||
import { layer } from "@layui/layer-vue";
|
||||
|
||||
import LayModal from "./module/layer/modal/index";
|
||||
import LayLayer from "./module/layer/index";
|
||||
import LayBacktop from "./module/backTop/index";
|
||||
import LayAvatar from "./module/avatar/index";
|
||||
import LayRadio from "./module/radio/index";
|
||||
@@ -40,7 +40,6 @@ import LayContainer from "./module/container/index";
|
||||
import LayCountUp from "./module/countUp/index";
|
||||
import LayMenu from "./module/menu/index";
|
||||
import LayMenuItem from "./module/menuItem/index";
|
||||
import LayMenuChildItem from "./module/menuChildItem/index";
|
||||
import LayCheckbox from "./module/checkbox/index";
|
||||
import LayCheckboxGroup from "./module/checkboxGroup/index";
|
||||
import LayForm from "./module/form/index";
|
||||
@@ -67,6 +66,10 @@ import LayCarouselItem from "./module/carouselItem/index";
|
||||
import LayColorPicker from "./module/colorPicker/index";
|
||||
import LayTooltip from "./module/tooltip/index";
|
||||
import LayInputNumber from "./module/inputNumber/index";
|
||||
import LaySkeleton from "./module/skeleton/index";
|
||||
import LaySkeletonItem from "./module/skeletonItem/index";
|
||||
import LayStep from "./module/step/index";
|
||||
import LayStepItem from "./module/stepItem/index";
|
||||
|
||||
const components: Record<string, IDefineComponent> = {
|
||||
LayRadio,
|
||||
@@ -99,7 +102,6 @@ const components: Record<string, IDefineComponent> = {
|
||||
LayContainer,
|
||||
LayMenu,
|
||||
LayMenuItem,
|
||||
LayMenuChildItem,
|
||||
LayCheckbox,
|
||||
LayForm,
|
||||
LayBreadcrumb,
|
||||
@@ -126,10 +128,14 @@ const components: Record<string, IDefineComponent> = {
|
||||
LayCarousel,
|
||||
LayCarouselItem,
|
||||
LayColorPicker,
|
||||
LayModal,
|
||||
LayLayer,
|
||||
LayTooltip,
|
||||
LayInputNumber,
|
||||
LaySkeleton,
|
||||
LaySkeletonItem,
|
||||
LayCountUp,
|
||||
LayStep,
|
||||
LayStepItem,
|
||||
};
|
||||
|
||||
const install = (app: App, options?: InstallOptions): void => {
|
||||
@@ -142,6 +148,10 @@ const install = (app: App, options?: InstallOptions): void => {
|
||||
};
|
||||
|
||||
export {
|
||||
LayStep,
|
||||
LayStepItem,
|
||||
LaySkeleton,
|
||||
LaySkeletonItem,
|
||||
LayRadio,
|
||||
LayIcon,
|
||||
LayButton,
|
||||
@@ -172,7 +182,6 @@ export {
|
||||
LayContainer,
|
||||
LayMenu,
|
||||
LayMenuItem,
|
||||
LayMenuChildItem,
|
||||
LayCheckbox,
|
||||
LayForm,
|
||||
LayBreadcrumb,
|
||||
@@ -199,7 +208,7 @@ export {
|
||||
LayCarousel,
|
||||
LayCarouselItem,
|
||||
LayColorPicker,
|
||||
LayModal
|
||||
LayLayer
|
||||
};
|
||||
|
||||
export { layer };
|
||||
|
||||
9
src/module/layer/index.ts
Normal file
9
src/module/layer/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { App } from "vue";
|
||||
import { LayLayer } from "@layui/layer-vue";
|
||||
import type { IDefineComponent } from "../type/index";
|
||||
|
||||
LayLayer.install = (app: App) => {
|
||||
app.component(LayLayer.name || "LayLayer", LayLayer);
|
||||
};
|
||||
|
||||
export default LayLayer as IDefineComponent;
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { App } from "vue";
|
||||
import { LayModal } from "@layui/layer-vue";
|
||||
import type { IDefineComponent } from "../../type/index";
|
||||
|
||||
LayModal.install = (app: App) => {
|
||||
app.component(LayModal.name || "LayModal", LayModal);
|
||||
};
|
||||
|
||||
export default LayModal as IDefineComponent;
|
||||
@@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<dd :class="[selectedKey === id ? 'layui-this' : '']" @click="selectHandle()">
|
||||
<slot v-if="slots.title" name="title"></slot>
|
||||
<a v-else href="javascript:void(0)">
|
||||
{{ title }}
|
||||
</a>
|
||||
</dd>
|
||||
</template>
|
||||
|
||||
<script setup name="LayMenuChildItem" lang="ts">
|
||||
import { defineProps, inject, Ref, useSlots } from "vue";
|
||||
|
||||
const slots = useSlots();
|
||||
|
||||
const props = defineProps<{
|
||||
id: string;
|
||||
title: string;
|
||||
}>();
|
||||
|
||||
const selectedKey: Ref<string> = inject("selectedKey") as Ref<string>;
|
||||
|
||||
const selectHandle = function () {
|
||||
selectedKey.value = props.id;
|
||||
};
|
||||
</script>
|
||||
@@ -6,7 +6,7 @@
|
||||
>
|
||||
<a href="javascript:void(0)" @click="openHandle">
|
||||
{{ title }}
|
||||
<i class="layui-icon layui-icon-down layui-nav-more"></i>
|
||||
<i :class="[openKeys.includes(id) && !isTree ? 'layui-nav-mored' : '']" class="layui-icon layui-icon-down layui-nav-more"></i>
|
||||
</a>
|
||||
<dl
|
||||
class="layui-nav-child"
|
||||
|
||||
@@ -14,21 +14,21 @@
|
||||
@attr : ~'[position=@{position}]';
|
||||
&{
|
||||
border: 1px solid @m-border-color;
|
||||
&.layui-popper@{attr}{
|
||||
margin-@{contrary_position}: 6px;
|
||||
.layui-popper-arrow {
|
||||
@{contrary_position}: -6px;
|
||||
border-@{contrary_position}-width: 0;
|
||||
border-@{position}-color: @m-border-color;
|
||||
&::after{
|
||||
@{contrary_position}: 1px;
|
||||
&@{attr}{
|
||||
margin-@{contrary_position}: 6px;
|
||||
.layui-popper-arrow {
|
||||
@{contrary_position}: -6px;
|
||||
border-@{contrary_position}-width: 0;
|
||||
margin-@{margin_postion}: -6px;
|
||||
border-@{position}-color: @color;
|
||||
border-@{position}-color: @m-border-color;
|
||||
&::after{
|
||||
@{contrary_position}: 1px;
|
||||
border-@{contrary_position}-width: 0;
|
||||
margin-@{margin_postion}: -6px;
|
||||
border-@{position}-color: @color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 统一设置四个方向的主题
|
||||
.theme(@background-color, @color, @border-color) {
|
||||
@@ -43,7 +43,7 @@
|
||||
// 箭头默认居中
|
||||
.arrow-default-center(@position, @prop) {
|
||||
@attr : ~'[position=@{position}]';
|
||||
&.layui-popper@{attr} {
|
||||
&@{attr} {
|
||||
.layui-popper-arrow{
|
||||
@{prop}: -moz-calc(50% - 6px);
|
||||
@{prop}: -webkit-calc(50% - 6px);
|
||||
@@ -58,6 +58,23 @@
|
||||
.arrow-default-center(right, top);
|
||||
}
|
||||
|
||||
// 填充popper,支持可以移动到popper使用到
|
||||
.single-fill-popper(@position, @contrary_position, @zeroPosition, @all, @seven){
|
||||
@attr : ~'[position=@{position}]';
|
||||
&@{attr}::after{
|
||||
@{contrary_position}: -7px;
|
||||
@{zeroPosition}: 0;
|
||||
@{all}: 100%;
|
||||
@{seven}: 7px;
|
||||
}
|
||||
}
|
||||
.fill-popper(){
|
||||
.single-fill-popper(top, bottom, left, width, height);
|
||||
.single-fill-popper(bottom, top, left, width, height);
|
||||
.single-fill-popper(left, right, bottom, height, width);
|
||||
.single-fill-popper(right, left, bottom, height, width);
|
||||
}
|
||||
|
||||
// 样式开始
|
||||
.layui-popper {
|
||||
position: fixed;
|
||||
@@ -76,9 +93,17 @@
|
||||
// 箭头默认居中
|
||||
.all-arrow-default-center();
|
||||
|
||||
&::after{
|
||||
content: " ";
|
||||
position: absolute;
|
||||
display: block;
|
||||
}
|
||||
// 填充
|
||||
.fill-popper();
|
||||
|
||||
.layui-popper-arrow {
|
||||
&,&::after{
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
<template>
|
||||
<transition v-show="innerVisible">
|
||||
<div
|
||||
ref="popper"
|
||||
:class="['layui-popper', { 'layui-dark': innnerIsDark }]"
|
||||
:style="style"
|
||||
:position="innnerPosition"
|
||||
>
|
||||
<slot>{{ content.value }}</slot>
|
||||
<div class="layui-popper-arrow"></div>
|
||||
</div>
|
||||
</transition>
|
||||
<teleport to="body" v-if="isExist">
|
||||
<transition v-show="innerVisible">
|
||||
<div
|
||||
ref="popper"
|
||||
:class="['layui-popper', { 'layui-dark': isDark }]"
|
||||
:style="style"
|
||||
:position="position"
|
||||
>
|
||||
<slot>{{ content }}</slot>
|
||||
<div class="layui-popper-arrow"></div>
|
||||
</div>
|
||||
</transition>
|
||||
</teleport>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
const NAME = "LayPopper";
|
||||
@@ -25,30 +27,33 @@ import {
|
||||
CSSProperties,
|
||||
ref,
|
||||
watch,
|
||||
onUpdated,
|
||||
defineEmits,
|
||||
onMounted,
|
||||
Ref,
|
||||
} from "vue";
|
||||
import { on } from "../../tools/domUtil";
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
el: any;
|
||||
content?: Ref<string | Number>;
|
||||
position?: Ref<string>;
|
||||
content?: string | Number;
|
||||
position?: string;
|
||||
trigger?: string;
|
||||
enterable?: boolean;
|
||||
isDark?: Ref<boolean>;
|
||||
disabled?: Ref<boolean>;
|
||||
visible?: Ref<boolean>;
|
||||
isCanHide?: Ref<boolean>;
|
||||
updateVisible?: Function;
|
||||
isDark?: boolean;
|
||||
disabled?: boolean;
|
||||
visible?: boolean;
|
||||
isCanHide?: boolean;
|
||||
}>(),
|
||||
{
|
||||
position: 'top',
|
||||
isDark: true,
|
||||
disabled: false,
|
||||
enterable: true,
|
||||
visible: true,
|
||||
isCanHide: true,
|
||||
trigger: "hover",
|
||||
}
|
||||
);
|
||||
const emit = defineEmits(["update:visible"]);
|
||||
|
||||
const EVENT_MAP: any = {
|
||||
hover: ["mouseenter", null, "mouseleave", false],
|
||||
@@ -63,55 +68,52 @@ if (!triggerArr) {
|
||||
const style = ref<CSSProperties>({ top: -window.innerHeight + "px", left: 0 });
|
||||
const checkTarget = ref(false);
|
||||
const popper = ref<HTMLDivElement>({} as HTMLDivElement);
|
||||
const tempPosition = props.position ?? ref("top");
|
||||
const innnerPosition = ref(tempPosition.value);
|
||||
const innnerIsDark = ref(props.isDark ?? true);
|
||||
const innnerDisabled = ref(props.disabled ?? false);
|
||||
const innnerPosition = ref(props.position);
|
||||
const innerVisible = ref(props.visible ?? true);
|
||||
const isExist = ref(false);
|
||||
|
||||
watch(innerVisible, (val) => {
|
||||
invokeShowPosistion();
|
||||
props.updateVisible && props.updateVisible(val);
|
||||
emit("update:visible", val);
|
||||
});
|
||||
watch(innnerDisabled, (val) => {
|
||||
innerVisible.value = false;
|
||||
watch(popper, (val) => {
|
||||
if (props.trigger === 'hover' && props.enterable) {
|
||||
on(popper.value, EVENT_MAP['hover'][0], doShow);
|
||||
on(popper.value, EVENT_MAP['hover'][2], doHidden);
|
||||
}
|
||||
});
|
||||
watch(
|
||||
() => props.content?.value,
|
||||
() => props.content,
|
||||
(val) => {
|
||||
innerVisible.value && invokeShowPosistion();
|
||||
}
|
||||
);
|
||||
|
||||
const doShow = function () {
|
||||
if (!innnerDisabled.value) {
|
||||
if (!props.disabled) {
|
||||
innerVisible.value = true;
|
||||
isExist.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const doHidden = function (e: MouseEvent) {
|
||||
// ||(props.enterable && popper.value.contains(e.target as Node))
|
||||
if (
|
||||
(checkTarget.value && props.el.contains(e.target)) ||
|
||||
(props.enterable && popper.value.contains(e.target as Node))
|
||||
(checkTarget.value && props.el.contains(e.target))
|
||||
)
|
||||
return;
|
||||
// style.value = {top: (-window.innerHeight) + 'px',left:0};
|
||||
// popper.value.remove();
|
||||
if (props.isCanHide?.value !== false) {
|
||||
if (props.isCanHide !== false) {
|
||||
innerVisible.value = false;
|
||||
}
|
||||
innnerPosition.value = tempPosition.value;
|
||||
innnerPosition.value = props.position;
|
||||
};
|
||||
|
||||
// 事件绑定
|
||||
on(props.el, triggerArr[0], doShow);
|
||||
on(triggerArr[1] ?? props.el, triggerArr[2], doHidden);
|
||||
checkTarget.value = triggerArr[3];
|
||||
|
||||
// 计算位置显示
|
||||
const showPosistion = function () {
|
||||
postionFns[tempPosition.value] &&
|
||||
(style.value = postionFns[tempPosition.value](
|
||||
postionFns[props.position] &&
|
||||
(style.value = postionFns[props.position](
|
||||
props.el,
|
||||
popper.value,
|
||||
innnerPosition
|
||||
@@ -126,6 +128,12 @@ const invokeShowPosistion = function () {
|
||||
setTimeout(() => innerVisible.value && showPosistion(), 2);
|
||||
}
|
||||
};
|
||||
|
||||
// 事件绑定
|
||||
on(props.el, triggerArr[0], doShow);
|
||||
on(triggerArr[1] ?? props.el, triggerArr[2], doHidden);
|
||||
checkTarget.value = triggerArr[3];
|
||||
|
||||
onMounted(() => {
|
||||
invokeShowPosistion();
|
||||
});
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
import { h, ref, render, watchEffect, watch } from "vue";
|
||||
import popper from "./index.vue";
|
||||
import { once } from "../../tools/domUtil";
|
||||
const EVENT_MAP: any = {
|
||||
hover: "mouseenter",
|
||||
click: "click",
|
||||
};
|
||||
const usePopper = {
|
||||
createPopper(el: HTMLElement, props: any, trigger: string) {
|
||||
const _this = this;
|
||||
once(el, EVENT_MAP[trigger], () => {
|
||||
// TODO 临时解决方案
|
||||
const _props: any = { el };
|
||||
for (const key in props) {
|
||||
_props[key] = ref(props[key]);
|
||||
}
|
||||
_props.updateVisible = function (val: boolean) {
|
||||
_props.visible && (_props.visible.value = val);
|
||||
};
|
||||
_this.renderPopper(_props);
|
||||
watchEffect(() => {
|
||||
for (const key in _props) {
|
||||
if (key === "visible") {
|
||||
continue;
|
||||
}
|
||||
_props[key].value = props[key];
|
||||
}
|
||||
});
|
||||
watch(
|
||||
() => props.visible,
|
||||
(val: boolean) => {
|
||||
_props.updateVisible(val);
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
renderPopper(props: any) {
|
||||
const container: HTMLDivElement = document.createElement("div");
|
||||
// container.setAttribute("class", "lay-div");
|
||||
const node = h(popper, props);
|
||||
render(node, container);
|
||||
container.firstElementChild &&
|
||||
document.body.appendChild(container.firstElementChild);
|
||||
return node;
|
||||
},
|
||||
};
|
||||
export default usePopper;
|
||||
72
src/module/skeleton/index.less
Normal file
72
src/module/skeleton/index.less
Normal file
@@ -0,0 +1,72 @@
|
||||
.lay-skeleton{
|
||||
.lay-skeleton-item {
|
||||
height: 16px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 16px;
|
||||
background: #eeeeee;
|
||||
}
|
||||
.lay-skeleton-type--p{
|
||||
height: 16px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 16px;
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
.lay-skeleton-type--image{
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
background: #eeeeee;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
i{
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lay-skeleton-animated {
|
||||
.lay-skeleton-type--image{
|
||||
width: 240px;
|
||||
height: 240px !important;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
i{
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
.lay-skeleton-item {
|
||||
height: 16px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 16px;
|
||||
background: #eeeeee;
|
||||
background: linear-gradient(
|
||||
90deg,#f2f2f2 25%,#ececec 37%,#f2f2f2 63%);
|
||||
background-size: 400% 100%;
|
||||
animation: lay-skeleton-loading 1.2s ease infinite;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
.lay-skeleton-first {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.lay-skeleton-last {
|
||||
width: 62.8%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes lay-skeleton-loading {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
}
|
||||
9
src/module/skeleton/index.ts
Normal file
9
src/module/skeleton/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { App } from 'vue'
|
||||
import Component from './index.vue'
|
||||
import type { IDefineComponent } from '../type/index'
|
||||
|
||||
Component.install = (app: App) => {
|
||||
app.component(Component.name || 'LaySkeleton', Component)
|
||||
}
|
||||
|
||||
export default Component as IDefineComponent
|
||||
34
src/module/skeleton/index.vue
Normal file
34
src/module/skeleton/index.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div :class="['lay-skeleton', animated ? 'lay-skeleton-animated': '',]" v-bind="$attrs">
|
||||
<template v-if="loading">
|
||||
<slot name="skeleton">
|
||||
<lay-skeleton-item
|
||||
v-for="item in rows"
|
||||
:class="[
|
||||
item===1? 'lay-skeleton-first': '',
|
||||
item === rows? 'lay-skeleton-last': '']"
|
||||
type="p"
|
||||
></lay-skeleton-item>
|
||||
</slot>
|
||||
</template>
|
||||
<slot v-else></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="LaySkeleton" lang="ts">
|
||||
import LaySkeletonItem from '../skeletonItem/index.vue'
|
||||
import './index.less'
|
||||
import { defineProps, withDefaults} from "vue";
|
||||
|
||||
export interface LaySkeletonProps {
|
||||
rows?: number;
|
||||
loading?: boolean;
|
||||
animated?: boolean;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LaySkeletonProps>(), {
|
||||
rows: 4,
|
||||
loading: false,
|
||||
animated: false,
|
||||
});
|
||||
</script>-
|
||||
9
src/module/skeletonItem/index.ts
Normal file
9
src/module/skeletonItem/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { App } from 'vue'
|
||||
import Component from './index.vue'
|
||||
import type { IDefineComponent } from '../type/index'
|
||||
|
||||
Component.install = (app: App) => {
|
||||
app.component(Component.name || 'LaySkeletonItem', Component)
|
||||
}
|
||||
|
||||
export default Component as IDefineComponent
|
||||
19
src/module/skeletonItem/index.vue
Normal file
19
src/module/skeletonItem/index.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<div :class="['lay-skeleton-item',`lay-skeleton-type--${type}`]" v-bind="$attrs">
|
||||
<div v-if="type==='image'" >
|
||||
<lay-icon type="layui-icon-picture"></lay-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="LaySkeletonItem" lang="ts">
|
||||
import { defineProps, withDefaults} from "vue";
|
||||
|
||||
export interface LaySkeletonProps {
|
||||
type?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LaySkeletonProps>(), {
|
||||
type: 'p',
|
||||
});
|
||||
</script>-
|
||||
@@ -130,7 +130,7 @@ if (Array.isArray(props.modelValue)) {
|
||||
rangeValue.value = props.modelValue;
|
||||
}
|
||||
|
||||
let verticalRangeValue: any = toRef(props, "verticalrange");
|
||||
let verticalRangeValue: Ref<number[]> | any = toRef(props, "verticalrange");
|
||||
|
||||
const standardtracker = ref<HTMLElement | null>(null);
|
||||
const verticaltracker = ref<HTMLElement | null>(null);
|
||||
|
||||
191
src/module/step/index.less
Normal file
191
src/module/step/index.less
Normal file
@@ -0,0 +1,191 @@
|
||||
@width-height-pace: 20px;
|
||||
@step-color: #5FB878;
|
||||
|
||||
.lay-step{
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
.lay-step-item{
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.is-item-center{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lay-step-item-last {
|
||||
flex-grow: 0 !important;
|
||||
}
|
||||
.lay-step-item-pace{
|
||||
width: @width-height-pace;
|
||||
height: @width-height-pace;
|
||||
border: 2px #8D8D8D solid;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: @width-height-pace;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
.is-center{
|
||||
margin: 0 auto;
|
||||
}
|
||||
.lay-step-item-active{
|
||||
border: 2px @step-color solid;
|
||||
color: #FFFFFF;
|
||||
background: @step-color;
|
||||
}
|
||||
.lay-step-item-wait{
|
||||
border: 2px #000000 solid;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.lay-step-item--success {
|
||||
border: 2px @step-color solid;
|
||||
color: #FFFFFF;
|
||||
background: @step-color;
|
||||
}
|
||||
|
||||
.lay-step-item--fail{
|
||||
border: 2px #FF5722 solid;
|
||||
color: #FFFFFF;
|
||||
background: #FF5722;
|
||||
}
|
||||
|
||||
.lay-step-item--warning{
|
||||
border: 2px #FFB800 solid;
|
||||
color: #FFFFFF;
|
||||
background: #FFB800;
|
||||
}
|
||||
.lay-step-item--primary{
|
||||
border: 2px #1E9FFF solid;
|
||||
color: #FFFFFF;
|
||||
background: #1E9FFF;
|
||||
}
|
||||
|
||||
.lay-step-item-success {
|
||||
border: 2px @step-color solid;
|
||||
color: #FFFFFF;
|
||||
background: @step-color;
|
||||
}
|
||||
|
||||
.lay-step-item-fail{
|
||||
border: 2px #FF5722 solid;
|
||||
color: #FFFFFF;
|
||||
background: #FF5722;
|
||||
}
|
||||
|
||||
.lay-step-item-warning{
|
||||
border: 2px #FFB800 solid;
|
||||
color: #FFFFFF;
|
||||
background: #FFB800;
|
||||
}
|
||||
.lay-step-item-primary{
|
||||
border: 2px #1E9FFF solid;
|
||||
color: #FFFFFF;
|
||||
background: #1E9FFF;
|
||||
}
|
||||
|
||||
.lay-step-item-content{
|
||||
color: #8D8D8D;
|
||||
.lay-step-item-content-title{
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.lay-step-item-content-active{
|
||||
color: @step-color;
|
||||
}
|
||||
|
||||
.lay-step-item-content--success{
|
||||
color: @step-color;
|
||||
}
|
||||
.lay-step-item-content--fail{
|
||||
color: #FF5722;
|
||||
}
|
||||
.lay-step-item-content--warning{
|
||||
color: #FFB800;
|
||||
}
|
||||
.lay-step-item-content--primary{
|
||||
color: #1E9FFF;
|
||||
}
|
||||
|
||||
.lay-step-item-content-wait{
|
||||
color: #000000;
|
||||
}
|
||||
.lay-step-item-content-success{
|
||||
color: @step-color;
|
||||
}
|
||||
.lay-step-item-content-fail{
|
||||
color: #FF5722;
|
||||
}
|
||||
.lay-step-item-content-warning{
|
||||
color: #FFB800;
|
||||
}
|
||||
.lay-step-item-content-primary{
|
||||
color: #1E9FFF;
|
||||
}
|
||||
|
||||
|
||||
.lay-step-item-line{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.lay-step-item-line:before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: block;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
background: #C9C5C5;
|
||||
}
|
||||
.is-line-center:before {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.lay-step-item-line-active:before {
|
||||
transition: background 150ms;
|
||||
background: #5FB878 !important;
|
||||
}
|
||||
|
||||
.lay-step-item-line-fail:before {
|
||||
transition: background 150ms;
|
||||
background: #FF5722 !important;
|
||||
}
|
||||
|
||||
.lay-step-item-line-warning:before {
|
||||
transition: background 150ms;
|
||||
background: #FFB800 !important;
|
||||
}
|
||||
|
||||
.lay-step-item-line-primary:before {
|
||||
transition: background 150ms;
|
||||
background: #1E9FFF !important;
|
||||
}
|
||||
|
||||
}
|
||||
.lay-step-column {
|
||||
height: 100%;
|
||||
flex-flow: column;
|
||||
.lay-step-item-line{
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 24px;
|
||||
}
|
||||
.lay-step-item-line:before {
|
||||
z-index: -1;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: block;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
background: #C9C5C5;
|
||||
}
|
||||
.is-vertical{
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import Component from "./index.vue";
|
||||
import type { IDefineComponent } from "../type/index";
|
||||
|
||||
Component.install = (app: App) => {
|
||||
app.component(Component.name || "LayMenuChildItem", Component);
|
||||
app.component(Component.name || "laySetup", Component);
|
||||
};
|
||||
|
||||
export default Component as IDefineComponent;
|
||||
43
src/module/step/index.vue
Normal file
43
src/module/step/index.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div :class="['lay-step', direction !== 'vertical' ? '' : 'lay-step-column']">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="layStep" lang="ts">
|
||||
import { ref, watch, provide, defineProps, withDefaults } from "vue";
|
||||
import "./index.less";
|
||||
|
||||
export interface LayStepProps {
|
||||
active?: number;
|
||||
center?: boolean;
|
||||
direction?: string;
|
||||
space?: string;
|
||||
currentStatus?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LayStepProps>(), {
|
||||
active: 0,
|
||||
center: false,
|
||||
direction: "horizontal",
|
||||
space: "auto",
|
||||
currentStatus: "primary",
|
||||
});
|
||||
|
||||
const steps = ref([]);
|
||||
|
||||
watch(steps, () => {
|
||||
steps.value.forEach(
|
||||
(instance: { setIndex: (arg0: any) => void }, index: any) => {
|
||||
instance.setIndex(index);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
provide("LayStep", {
|
||||
props,
|
||||
steps,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
9
src/module/stepItem/index.ts
Normal file
9
src/module/stepItem/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { App } from "vue";
|
||||
import Component from "./index.vue";
|
||||
import type { IDefineComponent } from "../type/index";
|
||||
|
||||
Component.install = (app: App) => {
|
||||
app.component(Component.name || "laySetupItem", Component);
|
||||
};
|
||||
|
||||
export default Component as IDefineComponent;
|
||||
152
src/module/stepItem/index.vue
Normal file
152
src/module/stepItem/index.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<template>
|
||||
<div
|
||||
:class="[
|
||||
'lay-step-item',
|
||||
isLast && !isCenter ? 'lay-step-item-last' : '',
|
||||
isCenter ? 'is-item-center' : '',
|
||||
isVertical ? 'is-vertical' : '',
|
||||
]"
|
||||
:style="{ flexBasis: space, flexGrow: space === 'auto' ? 1 : 0 }"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
!isLast
|
||||
? isLineActive
|
||||
? `lay-step-item-line lay-step-item-line-${status || 'active'}`
|
||||
: 'lay-step-item-line'
|
||||
: '',
|
||||
isCenter ? 'is-line-center' : '',
|
||||
]"
|
||||
>
|
||||
<div
|
||||
:class="[
|
||||
'lay-step-item-pace',
|
||||
isActive ? `lay-step-item-active` : '',
|
||||
isCurrent === index ? `lay-step-item--${currentStatus}` : '',
|
||||
status ? `lay-step-item-${status}` : '',
|
||||
isWait ? 'lay-step-item-wait' : '',
|
||||
isCenter ? 'is-center' : '',
|
||||
]"
|
||||
>
|
||||
<slot name="pace">
|
||||
<template v-if="icon">
|
||||
<lay-icon :type="icon"></lay-icon>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span v-if="!isActive">{{ index + 1 }}</span>
|
||||
<lay-icon
|
||||
v-else
|
||||
:type="status === 'fail' ? 'layui-icon-close' : 'layui-icon-ok'"
|
||||
></lay-icon>
|
||||
</template>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
<slot>
|
||||
<div
|
||||
:class="[
|
||||
'lay-step-item-content',
|
||||
isActive ? `lay-step-item-content-active` : '',
|
||||
isCurrent === index ? `lay-step-item-content--${currentStatus}` : '',
|
||||
status ? `lay-step-item-content-${status}` : '',
|
||||
isWait ? 'lay-step-item-content-wait' : '',
|
||||
]"
|
||||
>
|
||||
<div class="lay-step-item-content-title">{{ title }}</div>
|
||||
<p>{{ content }}</p>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="LayStepItem" lang="ts">
|
||||
import {
|
||||
ref,
|
||||
inject,
|
||||
onMounted,
|
||||
computed,
|
||||
getCurrentInstance,
|
||||
onBeforeUnmount,
|
||||
reactive,
|
||||
defineProps,
|
||||
withDefaults,
|
||||
} from "vue";
|
||||
|
||||
import type { ComputedRef } from "vue";
|
||||
|
||||
export interface LayStepItemProps {
|
||||
title?: string;
|
||||
content?: string;
|
||||
icon?: string;
|
||||
status?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<LayStepItemProps>(), {
|
||||
title: "",
|
||||
content: "",
|
||||
icon: "",
|
||||
status: "",
|
||||
});
|
||||
|
||||
const index = ref(-1);
|
||||
const parents: any = inject("LayStep");
|
||||
const currentInstance: any = getCurrentInstance();
|
||||
const setIndex = (val: number) => {
|
||||
index.value = val;
|
||||
};
|
||||
|
||||
const stepsCount = computed(() => {
|
||||
return parents.steps.value.length;
|
||||
});
|
||||
|
||||
const currentStatus = computed(() => {
|
||||
return parents.props.currentStatus;
|
||||
});
|
||||
const isCurrent = computed(() => {
|
||||
return parents.props.active;
|
||||
});
|
||||
console.log(isCurrent);
|
||||
const space = computed(() => {
|
||||
return parents.props.space;
|
||||
});
|
||||
|
||||
const isVertical = computed(() => {
|
||||
return parents.props.direction === "vertical";
|
||||
});
|
||||
|
||||
const isCenter = computed(() => {
|
||||
return parents.props.center;
|
||||
});
|
||||
|
||||
const isLineActive: ComputedRef<boolean> = computed(() => {
|
||||
return index.value <= parents.props.active - 1;
|
||||
});
|
||||
|
||||
const isWait: ComputedRef<boolean> = computed(() => {
|
||||
return index.value === parents.props.active + 1;
|
||||
});
|
||||
|
||||
const isActive: ComputedRef<boolean> = computed(() => {
|
||||
return index.value <= parents.props.active;
|
||||
});
|
||||
const isLast: ComputedRef<boolean> = computed(() => {
|
||||
return (
|
||||
parents.steps.value[stepsCount.value - 1]?.itemId === currentInstance.uid
|
||||
);
|
||||
});
|
||||
|
||||
const stepItemState = reactive({
|
||||
itemId: computed(() => currentInstance?.uid),
|
||||
setIndex,
|
||||
});
|
||||
|
||||
parents.steps.value = [...parents.steps.value, stepItemState];
|
||||
|
||||
onMounted(() => {});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
parents.steps.value = parents.steps.value.filter(
|
||||
(instance: { itemId: any }) => instance.itemId !== currentInstance.uid
|
||||
);
|
||||
});
|
||||
</script>
|
||||
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<li class="layui-timeline-item">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
<i class="layui-icon layui-timeline-axis" v-if="slot.dot">
|
||||
<slot name="dot"></slot>
|
||||
</i>
|
||||
<i class="layui-icon layui-timeline-axis" v-else></i>
|
||||
<div class="layui-timeline-content layui-text">
|
||||
<div v-if="simple" class="layui-timeline-title">
|
||||
{{ title }}
|
||||
@@ -20,7 +23,9 @@ export default {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps } from "vue";
|
||||
import { defineProps, useSlots } from "vue";
|
||||
|
||||
const slot = useSlots();
|
||||
|
||||
export interface LayTimelineItemProps {
|
||||
title: string;
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
<template>
|
||||
<slot></slot>
|
||||
<lay-popper v-if="isMounted" v-bind="innerProps"></lay-popper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import usePopper from "../popper/usePopper";
|
||||
import { defineComponent } from "vue";
|
||||
import LayPopper from "../popper/index.vue";
|
||||
import { defineComponent, ref } from "vue";
|
||||
export default defineComponent({
|
||||
name: "LayTooltip",
|
||||
components: {
|
||||
LayPopper
|
||||
},
|
||||
props: {
|
||||
content: {
|
||||
type: [Number, String],
|
||||
@@ -22,21 +29,26 @@ export default defineComponent({
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: false,
|
||||
},
|
||||
isCanHide: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
setup(){
|
||||
const isMounted = ref(false);
|
||||
return {
|
||||
isMounted
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
innerProps(){
|
||||
return {el: this.$el.nextElementSibling, ...this.$props};
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const _this = this;
|
||||
this.$nextTick(() => {
|
||||
usePopper.createPopper(_this.$el, _this.$props, "hover");
|
||||
});
|
||||
},
|
||||
render() {
|
||||
return this.$slots.default && this.$slots.default()[0];
|
||||
},
|
||||
this.$nextTick(() => this.isMounted = true);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user