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,35 @@
import type {
ValidateCallback,
ValidateError,
ValidateMessages,
} from "async-validator";
export interface LayFormContext {
model: modelType;
required?: boolean;
requiredErrorMessage?: string;
validateMessage: ValidateMessages;
rules?: Record<string, unknown>;
useCN: boolean;
requiredIcons?: string;
addField: (field: LayFormItemContext) => void;
}
export interface LayFormItemContext {
prop?: string;
$el: HTMLDivElement;
required?: boolean;
rules?: Record<string, unknown>;
validate(callback?: ValidateCallback): void;
clearValidate(): void;
}
export declare type modelType = { [key: string]: any };
export declare interface FormCallback {
(isValid?: boolean, model?: modelType, errors?: ValidateError[] | null): void;
}
export declare interface FieldValidateError extends ValidateError {
label?: string;
}

View File

@@ -0,0 +1,232 @@
::: anchor
:::
::: title 基本介绍
:::
::: describe 最基础的卡片容器,可承载文字、列表、图片、段落,常用于后台概览页面。
:::
::: title 基础使用
:::
::: demo 使用 `lay-card` 标签, 创建卡片组件
<template>
<div class="card-container">
<lay-card title="标题">
内容
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 卡片插槽
:::
::: demo
<template>
<div class="card-container">
<lay-card>
<template v-slot:title>
标题
</template>
<template v-slot:body>
内容
</template>
<template v-slot:footer>
底部
</template>
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 简单使用
:::
::: demo
<template>
<div class="card-container">
<lay-card>
内容
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 使用插槽
:::
::: demo
<template>
<div class="card-container">
<lay-card>
<template v-slot:title>
标题
</template>
<template v-slot:extra>
更多
</template>
<template v-slot:body>
内容
</template>
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title 边框阴影
:::
::: demo 通过 shadow 属性设置卡片阴影出现的时机。 该属性的值可以是always、hover或never。
<template>
<div class="card-container">
<lay-card>
内容
</lay-card>
<lay-card shadow="hover">
内容
</lay-card>
<lay-card shadow="never">
内容
</lay-card>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
return {
}
}
}
</script>
<style>
.card-container {
background: whitesmoke;
padding: 20px;
}
</style>
:::
::: title Card 属性
:::
::: table
| 属性 | 描述 | 类型 | 可选值 | 可选值 |
| ----- | ---- | ------ | ----- | ----- |
| title | 标题 | `string` | -- | -- |
| shadow | 阴影 | `string` | `always` | `always` `hover` `never` |
:::
::: title Card 插槽
:::
::: table
| 插槽 | 描述 | 可选值 | 版本 |
| ------- | -------- | ------ |------ |
| default | 默认插槽 | -- |-- |
| header | 头部插槽 | -- |-- |
| body | 内容插槽 | -- |-- |
| extra | 扩展插槽 | -- |-- |
| footer | 扩展插槽 | -- |`1.4.3`|
:::
::: contributor card
:::
::: previousNext card
:::

View File

@@ -0,0 +1,101 @@
@import "../input/index.less";
@lg: 44px;
@md: 38px;
@sm: 32px;
@xs: 26px;
@lg-width: 260px;
@md-width: 220px;
@sm-width: 180px;
@xs-width: 140px;
.set-size(@size, @width) {
& {
height: @size;
width: @width;
.layui-input {
height: @size;
line-height: @size;
}
}
}
.layui-cascader {
display: inline-block;
&[size="lg"] {
.set-size(@lg,@lg-width);
}
&[size="md"] {
.set-size(@md,@md-width);
}
&[size="sm"] {
.set-size(@sm,@sm-width);
}
&[size="xs"] {
.set-size(@xs,@xs-width);
}
}
.layui-cascader .layui-input-suffix{
padding-right: 10px;
}
.layui-cascader .layui-icon-triangle-d {
transition: all 0.3s ease-in-out;
transform: rotate(0);
color:var(--global-neutral-color-8);
}
.layui-cascader-opend .layui-icon-triangle-d {
transform: rotate(180deg);
}
.layui-cascader .layui-cascader-panel {
box-sizing: border-box;
border-radius: 2px;
line-height: 26px;
color: #000c;
font-size: 14px;
white-space: nowrap;
display: inline-flex;
}
.layui-cascader-menu {
display: inline-block;
border-right: 1px solid var(--global-neutral-color-3);
}
.layui-cascader-menu:last-child {
border-right: none;
}
.layui-cascader-menu-item {
min-width: 130px;
padding: 5px 15px;
box-sizing: border-box;
transition: all 0.1s ease-in-out;
display: flex;
justify-content: space-between;
align-items: center;
padding-right: 9px;
min-height: 35px;
}
.layui-cascader-menu-item:hover {
background-color: var(--global-checked-color);
color: white;
}
.layui-cascader-selected {
background-color: var(--global-checked-color);
color: white;
}
.layui-cascader-menu-item .layui-icon-right{
margin-left: 10px;
}
.layui-cascader-disabled,
.layui-cascader-disabled * {
cursor: not-allowed !important;
}

View File

@@ -0,0 +1,100 @@
<template>
<div class="layui-layer-phimg">
<img :src="imgList[index].src" />
<div class="layui-layer-imgsee" v-if="imgList.length > 0">
<span class="layui-layer-imguide" v-if="imgList.length > 1">
<a
href="javascript:;"
class="layui-layer-iconext layui-layer-imgprev"
@click="changeIndex(-1)"
></a>
<a
href="javascript:;"
class="layui-layer-iconext layui-layer-imgnext"
@click="changeIndex(1)"
></a>
</span>
<div
class="layui-layer-imgbar"
v-if="imgList.length > 1 || imgList[index].alt"
:style="{ opacity: showLayerImgBar ? 1 : 0 }"
>
<div class="thumb-row" v-if="ifSetThumb">
<div
class="thumb-box"
v-for="(item, i) in imgList"
:key="'thumb-box' + i"
@click="index = i"
>
<img :src="item.thumb" />
</div>
<div
class="thumb-box-border"
:style="{
left: `calc(calc( calc(100% - ${100 * imgList.length}px) / 2) + ${
index * 100
}px)`,
}"
></div>
</div>
<span class="layui-layer-imgtit" v-else>
<span v-if="imgList[index].alt">{{ imgList[index].alt }}</span>
<em v-if="imgList.length > 1"
>{{ index + 1 }} / {{ imgList.length }}</em
>
</span>
</div>
</div>
</div>
</template>
<script lang="ts">
export default {
name: "Photos",
};
</script>
<script lang="ts" setup>
import { watch, ref, onMounted, nextTick, computed } from "vue";
export interface LayPhotoProps {
imgList: { src: string; alt: string; thumb: string }[];
startIndex: number;
}
const emit = defineEmits(["resetCalculationPohtosArea"]);
const props = withDefaults(defineProps<LayPhotoProps>(), {
startIndex: 0,
});
const index = ref(props.startIndex);
watch(index, () => {
//当图片索引改变的时候 重新计算弹层的大小
emit("resetCalculationPohtosArea", index.value);
});
const changeIndex = (step: number) => {
let nowIndex = index.value;
let next = nowIndex + step;
if (next < 0) {
next = props.imgList.length - 1;
}
if (next >= props.imgList.length) {
next = 0;
}
index.value = next;
};
const showLayerImgBar = ref(false);
onMounted(() => {
nextTick(() => {
showLayerImgBar.value = true;
});
});
const ifSetThumb = computed(() => {
let res = false;
props.imgList.forEach((e) => {
if (e.thumb) {
res = true;
}
});
return res;
});
</script>

View File

@@ -0,0 +1,11 @@
<script lang="ts">
export default {
name: "LayDropdownMenu",
};
</script>
<template>
<ul class="layui-menu layui-dropdown-menu">
<slot></slot>
</ul>
</template>