集成 prettier 插件, 新增 npm run lint:prettier 命令

This commit is contained in:
就眠儀式 2021-12-24 13:42:56 +08:00
parent d814aca171
commit 6717dfead2
80 changed files with 1652 additions and 1450 deletions

3
.prettierrc Normal file
View File

@ -0,0 +1,3 @@
{
}

View File

@ -1,3 +0,0 @@
module.exports = {
}

View File

@ -25,7 +25,8 @@
"dev": "vite",
"build": "vite build --emptyOutDir && npm run build:types",
"build:types": "rimraf types && tsc -d",
"build:example": "vite build example"
"build:example": "vite build example",
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\""
},
"peerDependencies": {
"vue": "^3.2.26",
@ -53,6 +54,7 @@
"escape-html": "^1.0.3",
"less": "^4.1.2",
"markdown-it-container": "^3.0.0",
"prettier": "^2.5.1",
"prismjs": "^1.25.0",
"rimraf": "^3.0.2",
"rollup": "^2.61.0",

View File

@ -182,7 +182,7 @@ a cite {
}
.layui-clear:after {
content: '\20';
content: "\20";
clear: both;
*zoom: 1;
display: block;
@ -683,7 +683,7 @@ a cite {
color: #c2c2c2 !important;
}
.layui-input-number[type='number'] {
.layui-input-number[type="number"] {
-moz-appearance: textfield;
}
@ -740,8 +740,8 @@ a cite {
padding: 0 10px;
}
.layui-form input[type='checkbox'],
.layui-form input[type='radio'],
.layui-form input[type="checkbox"],
.layui-form input[type="radio"],
.layui-form select {
display: none;
}
@ -757,7 +757,7 @@ a cite {
}
.layui-form-item:after {
content: '\20';
content: "\20";
clear: both;
*zoom: 1;
display: block;
@ -1122,7 +1122,7 @@ a cite {
margin-top: 4px;
}
.layui-form-checkbox[lay-skin='primary'] {
.layui-form-checkbox[lay-skin="primary"] {
height: auto !important;
line-height: normal !important;
min-width: 18px;
@ -1134,7 +1134,7 @@ a cite {
background: 0 0;
}
.layui-form-checkbox[lay-skin='primary'] span {
.layui-form-checkbox[lay-skin="primary"] span {
padding-left: 0;
padding-right: 15px;
line-height: 18px;
@ -1142,7 +1142,7 @@ a cite {
color: #666;
}
.layui-form-checkbox[lay-skin='primary'] i {
.layui-form-checkbox[lay-skin="primary"] i {
right: auto;
left: 0;
width: 16px;
@ -1156,27 +1156,27 @@ a cite {
transition: 0.1s linear;
}
.layui-form-checkbox[lay-skin='primary']:hover i {
.layui-form-checkbox[lay-skin="primary"]:hover i {
border-color: #5fb878;
color: #fff;
}
.layui-form-checked[lay-skin='primary'] i {
.layui-form-checked[lay-skin="primary"] i {
border-color: #5fb878 !important;
background-color: #5fb878;
color: #fff;
}
.layui-checkbox-disabled[lay-skin='primary'] span {
.layui-checkbox-disabled[lay-skin="primary"] span {
background: 0 0 !important;
color: #c2c2c2 !important;
}
.layui-checkbox-disabled[lay-skin='primary']:hover i {
.layui-checkbox-disabled[lay-skin="primary"]:hover i {
border-color: #d2d2d2;
}
.layui-form-item .layui-form-checkbox[lay-skin='primary'] {
.layui-form-item .layui-form-checkbox[lay-skin="primary"] {
margin-top: 10px;
}
@ -1391,7 +1391,7 @@ a cite {
}
.layui-form-item .layui-inline:after {
content: '\20';
content: "\20";
clear: both;
display: block;
height: 0;
@ -1758,8 +1758,8 @@ a cite {
.layui-table-tool,
.layui-table-total,
.layui-table-view,
.layui-table[lay-skin='line'],
.layui-table[lay-skin='row'] {
.layui-table[lay-skin="line"],
.layui-table[lay-skin="row"] {
border-width: 1px;
border-style: solid;
border-color: #eee;
@ -1774,18 +1774,18 @@ a cite {
font-size: 14px;
}
.layui-table[lay-skin='line'] td,
.layui-table[lay-skin='line'] th {
.layui-table[lay-skin="line"] td,
.layui-table[lay-skin="line"] th {
border-width: 0 0 1px;
}
.layui-table[lay-skin='row'] td,
.layui-table[lay-skin='row'] th {
.layui-table[lay-skin="row"] td,
.layui-table[lay-skin="row"] th {
border-width: 0 1px 0 0;
}
.layui-table[lay-skin='nob'] td,
.layui-table[lay-skin='nob'] th {
.layui-table[lay-skin="nob"] td,
.layui-table[lay-skin="nob"] th {
border: none;
}
@ -1793,23 +1793,23 @@ a cite {
max-width: 100px;
}
.layui-table[lay-size='lg'] td,
.layui-table[lay-size='lg'] th {
.layui-table[lay-size="lg"] td,
.layui-table[lay-size="lg"] th {
padding: 15px 30px;
}
.layui-table-view .layui-table[lay-size='lg'] .layui-table-cell {
.layui-table-view .layui-table[lay-size="lg"] .layui-table-cell {
height: 40px;
line-height: 40px;
}
.layui-table[lay-size='sm'] td,
.layui-table[lay-size='sm'] th {
.layui-table[lay-size="sm"] td,
.layui-table[lay-size="sm"] th {
font-size: 12px;
padding: 5px 10px;
}
.layui-table-view .layui-table[lay-size='sm'] .layui-table-cell {
.layui-table-view .layui-table[lay-size="sm"] .layui-table-cell {
height: 20px;
line-height: 20px;
}
@ -1829,11 +1829,11 @@ a cite {
border-collapse: separate;
}
.layui-table-view .layui-table[lay-skin='line'] {
.layui-table-view .layui-table[lay-skin="line"] {
border-width: 0 1px 0 0;
}
.layui-table-view .layui-table[lay-skin='row'] {
.layui-table-view .layui-table[lay-skin="row"] {
border-width: 0 0 1px;
}
@ -1856,11 +1856,11 @@ a cite {
cursor: default;
}
.layui-table-view .layui-table td[data-edit='text'] {
.layui-table-view .layui-table td[data-edit="text"] {
cursor: text;
}
.layui-table-view .layui-form-checkbox[lay-skin='primary'] i {
.layui-table-view .layui-form-checkbox[lay-skin="primary"] i {
width: 18px;
height: 18px;
}
@ -1973,7 +1973,7 @@ a cite {
transition: all 0.3s;
}
.layui-table-tool-panel li .layui-form-checkbox[lay-skin='primary'] {
.layui-table-tool-panel li .layui-form-checkbox[lay-skin="primary"] {
width: 100%;
padding-left: 28px;
}
@ -1982,13 +1982,13 @@ a cite {
background-color: #f6f6f6;
}
.layui-table-tool-panel li .layui-form-checkbox[lay-skin='primary'] i {
.layui-table-tool-panel li .layui-form-checkbox[lay-skin="primary"] i {
position: absolute;
left: 0;
top: 0;
}
.layui-table-tool-panel li .layui-form-checkbox[lay-skin='primary'] span {
.layui-table-tool-panel li .layui-form-checkbox[lay-skin="primary"] span {
padding: 0;
}
@ -2042,11 +2042,11 @@ a cite {
border-top-color: #666;
}
.layui-table-sort[lay-sort='asc'] .layui-table-sort-asc {
.layui-table-sort[lay-sort="asc"] .layui-table-sort-asc {
border-bottom-color: #000;
}
.layui-table-sort[lay-sort='desc'] .layui-table-sort-desc {
.layui-table-sort[lay-sort="desc"] .layui-table-sort-desc {
border-top-color: #000;
}
@ -2057,7 +2057,7 @@ a cite {
box-sizing: border-box;
}
.layui-table-cell .layui-form-checkbox[lay-skin='primary'] {
.layui-table-cell .layui-form-checkbox[lay-skin="primary"] {
top: -1px;
padding: 0;
}
@ -2527,7 +2527,7 @@ body .layui-table-tips .layui-layer-content {
top: 0;
bottom: 0;
border-right: 3px solid #5fb878;
content: '';
content: "";
}
.layui-menu-body-title {
@ -2564,7 +2564,7 @@ body .layui-table-tips .layui-layer-content {
}
.layui-menu-body-panel:before {
content: '';
content: "";
position: absolute;
width: 20px;
left: -16px;
@ -2618,13 +2618,13 @@ body .layui-table-tips .layui-layer-content {
background-color: #fff;
box-sizing: border-box;
}
.layui-dropdown dl::before{
content: ' ';
.layui-dropdown dl::before {
content: " ";
display: block;
height: 4px;
width: 100%;
}
.layui-dropdown dl>.layui-dropdown-menu{
.layui-dropdown dl > .layui-dropdown-menu {
border: 1px solid #eee;
border-radius: 4px;
}
@ -2876,7 +2876,7 @@ body .layui-table-tips .layui-layer-content {
.layui-nav .layui-this:after,
.layui-nav-bar {
content: '';
content: "";
position: absolute;
left: 0;
top: 0;
@ -2892,7 +2892,7 @@ body .layui-table-tips .layui-layer-content {
z-index: 1000;
}
.layui-nav[lay-bar='disabled'] .layui-nav-bar {
.layui-nav[lay-bar="disabled"] .layui-nav-bar {
display: none;
}
@ -3181,7 +3181,7 @@ body .layui-table-tips .layui-layer-content {
position: absolute;
left: 0;
top: 0;
content: '';
content: "";
width: 100%;
height: 41px;
border-width: 1px;
@ -3363,7 +3363,7 @@ body .layui-table-tips .layui-layer-content {
.layui-carousel > [carousel-item]:before {
position: absolute;
content: '\e63d';
content: "\e63d";
left: 50%;
top: 50%;
width: 100px;
@ -3416,22 +3416,22 @@ body .layui-table-tips .layui-layer-content {
cursor: pointer;
}
.layui-carousel-arrow[lay-type='add'] {
.layui-carousel-arrow[lay-type="add"] {
left: auto !important;
right: 10px;
}
.layui-carousel:hover .layui-carousel-arrow[lay-type='add'],
.layui-carousel[lay-arrow='always'] .layui-carousel-arrow[lay-type='add'] {
.layui-carousel:hover .layui-carousel-arrow[lay-type="add"],
.layui-carousel[lay-arrow="always"] .layui-carousel-arrow[lay-type="add"] {
right: 20px;
}
.layui-carousel[lay-arrow='always'] .layui-carousel-arrow {
.layui-carousel[lay-arrow="always"] .layui-carousel-arrow {
opacity: 1;
left: 20px;
}
.layui-carousel[lay-arrow='none'] .layui-carousel-arrow {
.layui-carousel[lay-arrow="none"] .layui-carousel-arrow {
display: none;
}
@ -3455,19 +3455,19 @@ body .layui-table-tips .layui-layer-content {
font-size: 0;
}
.layui-carousel[lay-indicator='outside'] {
.layui-carousel[lay-indicator="outside"] {
margin-bottom: 30px;
}
.layui-carousel[lay-indicator='outside'] .layui-carousel-ind {
.layui-carousel[lay-indicator="outside"] .layui-carousel-ind {
top: 10px;
}
.layui-carousel[lay-indicator='outside'] .layui-carousel-ind ul {
.layui-carousel[lay-indicator="outside"] .layui-carousel-ind ul {
background-color: rgba(0, 0, 0, 0.5);
}
.layui-carousel[lay-indicator='none'] .layui-carousel-ind {
.layui-carousel[lay-indicator="none"] .layui-carousel-ind {
display: none;
}
@ -3533,23 +3533,23 @@ body .layui-table-tips .layui-layer-content {
left: 100%;
}
.layui-carousel[lay-anim='updown'] .layui-carousel-arrow {
.layui-carousel[lay-anim="updown"] .layui-carousel-arrow {
left: 50% !important;
top: 20px;
margin: 0 0 0 -18px;
}
.layui-carousel[lay-anim='updown'] > [carousel-item] > *,
.layui-carousel[lay-anim='fade'] > [carousel-item] > * {
.layui-carousel[lay-anim="updown"] > [carousel-item] > *,
.layui-carousel[lay-anim="fade"] > [carousel-item] > * {
left: 0 !important;
}
.layui-carousel[lay-anim='updown'] .layui-carousel-arrow[lay-type='add'] {
.layui-carousel[lay-anim="updown"] .layui-carousel-arrow[lay-type="add"] {
top: auto !important;
bottom: 20px;
}
.layui-carousel[lay-anim='updown'] .layui-carousel-ind {
.layui-carousel[lay-anim="updown"] .layui-carousel-ind {
position: absolute;
top: 50%;
right: 20px;
@ -3557,66 +3557,66 @@ body .layui-table-tips .layui-layer-content {
height: auto;
}
.layui-carousel[lay-anim='updown'] .layui-carousel-ind ul {
.layui-carousel[lay-anim="updown"] .layui-carousel-ind ul {
padding: 3px 5px;
}
.layui-carousel[lay-anim='updown'] .layui-carousel-ind li {
.layui-carousel[lay-anim="updown"] .layui-carousel-ind li {
display: block;
margin: 6px 0;
}
.layui-carousel[lay-anim='updown'] > [carousel-item] > .layui-this {
.layui-carousel[lay-anim="updown"] > [carousel-item] > .layui-this {
top: 0;
}
.layui-carousel[lay-anim='updown'] > [carousel-item] > .layui-carousel-prev {
.layui-carousel[lay-anim="updown"] > [carousel-item] > .layui-carousel-prev {
top: -100%;
}
.layui-carousel[lay-anim='updown'] > [carousel-item] > .layui-carousel-next {
.layui-carousel[lay-anim="updown"] > [carousel-item] > .layui-carousel-next {
top: 100%;
}
.layui-carousel[lay-anim='updown']
.layui-carousel[lay-anim="updown"]
> [carousel-item]
> .layui-carousel-next.layui-carousel-left,
.layui-carousel[lay-anim='updown']
.layui-carousel[lay-anim="updown"]
> [carousel-item]
> .layui-carousel-prev.layui-carousel-right {
top: 0;
}
.layui-carousel[lay-anim='updown']
.layui-carousel[lay-anim="updown"]
> [carousel-item]
> .layui-this.layui-carousel-left {
top: -100%;
}
.layui-carousel[lay-anim='updown']
.layui-carousel[lay-anim="updown"]
> [carousel-item]
> .layui-this.layui-carousel-right {
top: 100%;
}
.layui-carousel[lay-anim='fade'] > [carousel-item] > .layui-carousel-next,
.layui-carousel[lay-anim='fade'] > [carousel-item] > .layui-carousel-prev {
.layui-carousel[lay-anim="fade"] > [carousel-item] > .layui-carousel-next,
.layui-carousel[lay-anim="fade"] > [carousel-item] > .layui-carousel-prev {
opacity: 0;
}
.layui-carousel[lay-anim='fade']
.layui-carousel[lay-anim="fade"]
> [carousel-item]
> .layui-carousel-next.layui-carousel-left,
.layui-carousel[lay-anim='fade']
.layui-carousel[lay-anim="fade"]
> [carousel-item]
> .layui-carousel-prev.layui-carousel-right {
opacity: 1;
}
.layui-carousel[lay-anim='fade']
.layui-carousel[lay-anim="fade"]
> [carousel-item]
> .layui-this.layui-carousel-left,
.layui-carousel[lay-anim='fade']
.layui-carousel[lay-anim="fade"]
> [carousel-item]
> .layui-this.layui-carousel-right {
opacity: 0;
@ -4078,7 +4078,7 @@ body .layui-util-face .layui-layer-content {
}
.layui-slider-wrap:after {
content: '';
content: "";
height: 100%;
display: inline-block;
vertical-align: middle;
@ -4110,7 +4110,7 @@ body .layui-util-face .layui-layer-content {
}
.layui-slider-tips:after {
content: '';
content: "";
position: absolute;
bottom: -12px;
left: 50%;
@ -4252,7 +4252,7 @@ body .layui-util-face .layui-layer-content {
}
.layui-tree-line .layui-tree-set .layui-tree-set:after {
content: '';
content: "";
position: absolute;
top: 14px;
left: -9px;
@ -4288,7 +4288,7 @@ body .layui-util-face .layui-layer-content {
}
.layui-tree-line .layui-tree-set:before {
content: '';
content: "";
position: absolute;
top: 0;
left: -9px;
@ -4335,7 +4335,7 @@ body .layui-util-face .layui-layer-content {
}
.layui-tree-iconArrow:after {
content: '';
content: "";
position: absolute;
left: 4px;
top: 3px;

View File

@ -1,42 +1,42 @@
.layui-avatar {
box-sizing: border-box;
margin: 0;
padding: 0;
color: #000000d9;
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5715;
list-style: none;
font-feature-settings: tnum;
position: relative;
display: inline-block;
overflow: hidden;
color: #fff;
white-space: nowrap;
text-align: center;
vertical-align: middle;
background: #ccc;
width: 32px;
height: 32px;
line-height: 32px;
border-radius: 4px;
}
.layui-avatar.layui-avatar-radius {
border-radius: 50%;
}
.layui-avatar.layui-avatar-sm {
height: 30px;
width: 30px;
}
.layui-avatar.layui-avatar-lg {
height: 36px;
width: 36px;
}
.layui-avatar.layui-avatar-xs {
height: 28px;
width: 28px;
}
box-sizing: border-box;
margin: 0;
padding: 0;
color: #000000d9;
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5715;
list-style: none;
font-feature-settings: tnum;
position: relative;
display: inline-block;
overflow: hidden;
color: #fff;
white-space: nowrap;
text-align: center;
vertical-align: middle;
background: #ccc;
width: 32px;
height: 32px;
line-height: 32px;
border-radius: 4px;
}
.layui-avatar.layui-avatar-radius {
border-radius: 50%;
}
.layui-avatar.layui-avatar-sm {
height: 30px;
width: 30px;
}
.layui-avatar.layui-avatar-lg {
height: 36px;
width: 36px;
}
.layui-avatar.layui-avatar-xs {
height: 28px;
width: 28px;
}

View File

@ -1,18 +1,18 @@
<script lang="ts">
export default {
name: "LayAvatar"
}
name: "LayAvatar",
};
</script>
<script setup lang="ts">
import { defineProps } from 'vue'
import "./index.less"
import { defineProps } from "vue";
import "./index.less";
const props = defineProps<{
src?: String
radius?: boolean
size?: string
}>()
src?: String;
radius?: boolean;
size?: string;
}>();
</script>
<template>
@ -24,4 +24,4 @@ const props = defineProps<{
size ? 'layui-avatar-' + size : '',
]"
/>
</template>
</template>

View File

@ -1,33 +1,33 @@
.layui-badge,
.layui-badge-dot,
.layui-badge-rim {
position: relative;
display: inline-block;
padding: 0 6px;
font-size: 12px;
text-align: center;
background-color: #ff5722;
color: #fff;
border-radius: 2px;
position: relative;
display: inline-block;
padding: 0 6px;
font-size: 12px;
text-align: center;
background-color: #ff5722;
color: #fff;
border-radius: 2px;
}
.layui-badge {
height: 18px;
line-height: 18px;
height: 18px;
line-height: 18px;
}
.layui-badge-dot {
width: 8px;
height: 8px;
padding: 0;
border-radius: 50%;
width: 8px;
height: 8px;
padding: 0;
border-radius: 50%;
}
.layui-badge-rim {
height: 18px;
line-height: 18px;
border-width: 1px;
border-style: solid;
background-color: #fff;
color: #666;
}
height: 18px;
line-height: 18px;
border-width: 1px;
border-style: solid;
background-color: #fff;
color: #666;
}

View File

@ -35,4 +35,4 @@ const styles = computed(() => {
<span :class="classes" :style="styles">
<slot v-if="type != 'dot'" />
</span>
</template>
</template>

View File

@ -1,14 +1,14 @@
.layui-elem-quote {
margin-bottom: 10px;
padding: 15px;
line-height: 1.6;
border-left: 5px solid #5fb878;
border-radius: 0 2px 2px 0;
background-color: #fafafa;
margin-bottom: 10px;
padding: 15px;
line-height: 1.6;
border-left: 5px solid #5fb878;
border-radius: 0 2px 2px 0;
background-color: #fafafa;
}
.layui-quote-nm {
border-style: solid;
border-width: 1px 1px 1px 5px;
background: 0 0;
}
border-style: solid;
border-width: 1px 1px 1px 5px;
background: 0 0;
}

View File

@ -6,7 +6,7 @@ export default {
<script setup lang="ts">
import { defineProps } from "vue";
import "./index.less"
import "./index.less";
const props = defineProps<{
nm?: boolean;
@ -17,4 +17,4 @@ const props = defineProps<{
<blockquote class="layui-elem-quote" :class="{ 'layui-quote-nm': nm }">
<slot />
</blockquote>
</template>
</template>

View File

@ -1,8 +1,8 @@
.layui-body {
display: block;
flex: 1;
overflow: auto;
height: 100%;
box-sizing: border-box;
min-height: 300px;
}
display: block;
flex: 1;
overflow: auto;
height: 100%;
box-sizing: border-box;
min-height: 300px;
}

View File

@ -1,15 +1,15 @@
<script lang="ts">
export default {
name: 'LayBody',
}
name: "LayBody",
};
</script>
<script setup name="LayBody" lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>
<div class="layui-body">
<slot />
</div>
</template>
</template>

View File

@ -5,16 +5,16 @@
</template>
<script setup name="LayBreadcrumb" lang="ts">
import { defineProps, provide, withDefaults } from 'vue'
import { defineProps, provide, withDefaults } from "vue";
const props = withDefaults(
defineProps<{
separator?: string
separator?: string;
}>(),
{
separator: '/',
separator: "/",
}
)
);
provide('separator', props.separator)
provide("separator", props.separator);
</script>

View File

@ -11,13 +11,13 @@
</template>
<script setup name="LayBreadcrumbItem" lang="ts">
import { defineProps, inject, useSlots } from 'vue'
import { defineProps, inject, useSlots } from "vue";
const slot = useSlots()
const slot = useSlots();
const props = defineProps<{
title?: string
}>()
title?: string;
}>();
const separator = inject('separator')
const separator = inject("separator");
</script>

View File

@ -1,104 +1,104 @@
.layui-btn {
height: 38px;
line-height: 36px;
border: 1px solid transparent;
padding: 0 18px;
background-color: #009688;
color: #fff;
white-space: nowrap;
text-align: center;
font-size: 14px;
border-radius: 2px;
cursor: pointer;
height: 38px;
line-height: 36px;
border: 1px solid transparent;
padding: 0 18px;
background-color: #009688;
color: #fff;
white-space: nowrap;
text-align: center;
font-size: 14px;
border-radius: 2px;
cursor: pointer;
}
.layui-btn:hover {
opacity: 0.8;
filter: alpha(opacity=80);
color: #fff;
opacity: 0.8;
filter: alpha(opacity=80);
color: #fff;
}
.layui-btn:active {
opacity: 1;
filter: alpha(opacity=100);
opacity: 1;
filter: alpha(opacity=100);
}
.layui-btn+.layui-btn {
margin-left: 10px;
.layui-btn + .layui-btn {
margin-left: 10px;
}
.layui-btn-radius {
border-radius: 100px;
border-radius: 100px;
}
.layui-btn .layui-icon {
padding: 0 2px;
vertical-align: middle\9;
vertical-align: bottom;
padding: 0 2px;
vertical-align: middle\9;
vertical-align: bottom;
}
.layui-btn-primary {
border-color: #d2d2d2;
background: 0 0;
color: #666;
border-color: #d2d2d2;
background: 0 0;
color: #666;
}
.layui-btn-primary:hover {
border-color: #009688;
color: #333;
border-color: #009688;
color: #333;
}
.layui-btn-normal {
background-color: #1e9fff;
background-color: #1e9fff;
}
.layui-btn-warm {
background-color: #ffb800;
background-color: #ffb800;
}
.layui-btn-danger {
background-color: #ff5722;
background-color: #ff5722;
}
.layui-btn-checked {
background-color: #5fb878;
background-color: #5fb878;
}
.layui-btn-disabled,
.layui-btn-disabled:active,
.layui-btn-disabled:hover {
border-color: #eee !important;
background-color: #fbfbfb !important;
color: #d2d2d2 !important;
cursor: not-allowed !important;
opacity: 1;
border-color: #eee !important;
background-color: #fbfbfb !important;
color: #d2d2d2 !important;
cursor: not-allowed !important;
opacity: 1;
}
.layui-btn-lg {
height: 44px;
line-height: 44px;
padding: 0 25px;
font-size: 16px;
height: 44px;
line-height: 44px;
padding: 0 25px;
font-size: 16px;
}
.layui-btn-sm {
height: 30px;
line-height: 30px;
padding: 0 10px;
font-size: 12px;
height: 30px;
line-height: 30px;
padding: 0 10px;
font-size: 12px;
}
.layui-btn-xs {
height: 22px;
line-height: 22px;
padding: 0 5px;
font-size: 12px;
height: 22px;
line-height: 22px;
padding: 0 5px;
font-size: 12px;
}
.layui-btn-xs i {
font-size: 12px !important;
font-size: 12px !important;
}
.layui-btn-fluid {
width: 100%;
}
width: 100%;
}

View File

@ -51,14 +51,8 @@ const classes = computed(() => {
>
<i
v-if="loading"
class="
layui-icon
layui-icon-loading-one
layui-anim
layui-anim-rotate
layui-anim-loop
"
class="layui-icon layui-icon-loading-one layui-anim layui-anim-rotate layui-anim-loop"
></i>
<slot v-else />
</button>
</template>
</template>

View File

@ -1,16 +1,16 @@
.layui-btn-container {
font-size: 0;
font-size: 0;
}
.layui-btn-container .layui-btn {
margin-right: 10px;
margin-bottom: 10px;
margin-right: 10px;
margin-bottom: 10px;
}
.layui-btn-container .layui-btn+.layui-btn {
margin-left: 0;
.layui-btn-container .layui-btn + .layui-btn {
margin-left: 0;
}
.layui-table .layui-btn-container .layui-btn {
margin-bottom: 9px;
}
margin-bottom: 9px;
}

View File

@ -1,41 +1,41 @@
.layui-btn-group {
vertical-align: middle;
font-size: 0;
vertical-align: middle;
font-size: 0;
}
.layui-btn-group .layui-btn {
margin-left: 0 !important;
margin-right: 0 !important;
border-left: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 0;
margin-left: 0 !important;
margin-right: 0 !important;
border-left: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 0;
}
.layui-btn-group .layui-btn-primary {
border-left: none;
border-left: none;
}
.layui-btn-group .layui-btn-primary:hover {
border-color: #d2d2d2;
color: #009688;
border-color: #d2d2d2;
color: #009688;
}
.layui-btn-group .layui-btn:first-child {
border-left: none;
border-radius: 2px 0 0 2px;
border-left: none;
border-radius: 2px 0 0 2px;
}
.layui-btn-group .layui-btn-primary:first-child {
border-left: 1px solid #d2d2d2;
border-left: 1px solid #d2d2d2;
}
.layui-btn-group .layui-btn:last-child {
border-radius: 0 2px 2px 0;
border-radius: 0 2px 2px 0;
}
.layui-btn-group .layui-btn+.layui-btn {
margin-left: 0;
.layui-btn-group .layui-btn + .layui-btn {
margin-left: 0;
}
.layui-btn-group+.layui-btn-group {
margin-left: 10px;
}
.layui-btn-group + .layui-btn-group {
margin-left: 10px;
}

View File

@ -5,11 +5,11 @@ export default {
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>
<div class="layui-btn-group">
<slot />
</div>
</template>
</template>

View File

@ -1,41 +1,41 @@
.layui-card {
margin-bottom: 15px;
border-radius: 2px;
background-color: #fff;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
margin-bottom: 15px;
border-radius: 2px;
background-color: #fff;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
.layui-card:last-child {
margin-bottom: 0;
margin-bottom: 0;
}
.layui-card-header {
height: 42px;
line-height: 42px;
padding: 0 15px;
border-bottom: 1px solid #f6f6f6;
color: #333;
border-radius: 2px 2px 0 0;
font-size: 14px;
height: 42px;
line-height: 42px;
padding: 0 15px;
border-bottom: 1px solid #f6f6f6;
color: #333;
border-radius: 2px 2px 0 0;
font-size: 14px;
}
.layui-card-body {
padding: 10px 15px;
line-height: 24px;
padding: 10px 15px;
line-height: 24px;
}
.layui-card-body[pad15] {
padding: 15px;
padding: 15px;
}
.layui-card-body[pad20] {
padding: 20px;
padding: 20px;
}
.layui-card-body .layui-table {
margin: 5px 0;
margin: 5px 0;
}
.layui-card .layui-tab {
margin: 0;
}
margin: 0;
}

View File

@ -24,13 +24,13 @@
lay-type="sub"
@click="prev"
>
{{ anim === 'updown' ? '' : '' }}</button
{{ anim === "updown" ? "" : "" }}</button
><button
class="layui-icon layui-carousel-arrow"
lay-type="add"
@click="next"
>
{{ anim === 'updown' ? '' : '' }}
{{ anim === "updown" ? "" : "" }}
</button>
</div>
</template>
@ -42,68 +42,68 @@ import {
useSlots,
ref,
computed,
} from 'vue'
} from "vue";
const slot = useSlots() as any
const slots = slot.default && (slot.default() as any[])
const slot = useSlots() as any;
const slots = slot.default && (slot.default() as any[]);
const props = withDefaults(
defineProps<{
width?: string
height?: string
modelValue: string
anim?: string
arrow?: string
indicator?: string
width?: string;
height?: string;
modelValue: string;
anim?: string;
arrow?: string;
indicator?: string;
}>(),
{
width: '100%',
height: '280px',
anim: 'default',
arrow: 'hover',
indicator: 'inside',
width: "100%",
height: "280px",
anim: "default",
arrow: "hover",
indicator: "inside",
}
)
);
const active = computed({
get() {
return props.modelValue
return props.modelValue;
},
set(val) {
emit('update:modelValue', val)
emit("update:modelValue", val);
},
})
});
const emit = defineEmits(['update:modelValue', 'change'])
const emit = defineEmits(["update:modelValue", "change"]);
const change = function (id: any) {
emit('change', id)
active.value = id
}
emit("change", id);
active.value = id;
};
provide('active', active)
provide("active", active);
const prev = function () {
for (var i = 0; i < slots.length; i++) {
if (slots[i].props.id === active.value) {
if (i === 0) {
active.value = slots[slots.length - 1].props.id
active.value = slots[slots.length - 1].props.id;
}
active.value = slots[i - 1].props.id
break
active.value = slots[i - 1].props.id;
break;
}
}
}
};
const next = function () {
for (var i = 0; i < slots.length; i++) {
if (slots[i].props.id === active.value) {
if (i === slots.length - 1) {
active.value = slots[0].props.id
active.value = slots[0].props.id;
}
active.value = slots[i + 1].props.id
break
active.value = slots[i + 1].props.id;
break;
}
}
}
};
</script>

View File

@ -4,11 +4,11 @@
</li>
</template>
<script setup name="LayCarouselItem" lang="ts">
import { defineProps, inject } from 'vue'
import { defineProps, inject } from "vue";
const props = defineProps<{
id: string
}>()
id: string;
}>();
const active = inject('active')
const active = inject("active");
</script>

View File

@ -4,7 +4,6 @@
</div>
</template>
<script lang="ts">
export default {
name: "LayCheckboxGroup",

View File

@ -22,7 +22,7 @@ const classes = computed(() => {
return [
props.md ? `layui-col-md${props.md}` : "",
props.xs ? `layui-col-xs${props.xs}` : "",
props.sm ? `layui-col-sm${props.sm}` : "",
props.sm ? `layui-col-sm${props.sm}` : "",
props.lg ? `layui-col-lg${props.lg}` : "",
props.mdOffset ? `layui-col-md-offset${props.mdOffset}` : "",
props.xsOffset ? `layui-col-xs-offset${props.xsOffset}` : "",

View File

@ -6,7 +6,14 @@
<script setup name="LayCollapse"></script>
<script setup lang="ts">
import { withDefaults, defineProps, provide, ref, defineEmits, watch } from 'vue'
import {
withDefaults,
defineProps,
provide,
ref,
defineEmits,
watch,
} from "vue";
const props = withDefaults(
defineProps<{
@ -15,25 +22,24 @@ const props = withDefaults(
}>(),
{
modelValue: () => [],
accordion: false
accordion: false,
}
)
);
//
watch(
() => props.modelValue,
(val, oldVal)=>{
activeValues.value = ([] as any[]).concat(val)
() => props.modelValue,
(val, oldVal) => {
activeValues.value = ([] as any[]).concat(val);
}
)
const emit = defineEmits(["update:modelValue", "change"])
);
const emit = defineEmits(["update:modelValue", "change"]);
const activeValues = ref<Array<any>>(([] as any[]).concat(props.modelValue));
provide("layCollapse", {
accordion : props.accordion,
accordion: props.accordion,
activeValues,
emit
})
emit,
});
</script>

View File

@ -1,50 +1,60 @@
<template>
<div class="layui-colla-item">
<h2 :class="['layui-colla-title', {'layui-disabled' : disabled}]" @click="showHandle">
<slot name="title" :props="props">{{ title}}</slot>
<i class="layui-icon layui-colla-icon">{{ isShow ? '' : '' }}</i>
<h2
:class="['layui-colla-title', { 'layui-disabled': disabled }]"
@click="showHandle"
>
<slot name="title" :props="props">{{ title }}</slot>
<i class="layui-icon layui-colla-icon">{{ isShow ? "" : "" }}</i>
</h2>
<div class="layui-colla-content" :class="isShow ? 'layui-show' : ''">
<p>
<slot :props="props"/>
<slot :props="props" />
</p>
</div>
</div>
</template>
<script setup name="LayCollapseItem" lang="ts">
import { withDefaults, defineProps, inject, computed, ref } from 'vue'
import { withDefaults, defineProps, inject, computed, ref } from "vue";
const props = withDefaults(
defineProps<{
id: number | string
title: string
disabled?: boolean
id: number | string;
title: string;
disabled?: boolean;
}>(),
{
disabled: false
disabled: false,
}
)
);
const {accordion, activeValues, emit} = inject('layCollapse') as any
const { accordion, activeValues, emit } = inject("layCollapse") as any;
let isShow = computed(()=>{return activeValues.value.includes(props.id)})
let isShow = computed(() => {
return activeValues.value.includes(props.id);
});
const showHandle = function () {
if (props.disabled) {
return ;
return;
}
const _isShow = isShow.value;
//
if (accordion) {
activeValues.value = !_isShow ? [props.id] : [];
} else if (_isShow) { // -->
activeValues.value.splice(activeValues.value.indexOf(props.id), 1)
} else { // -->
activeValues.value.push(props.id)
} else if (_isShow) {
// -->
activeValues.value.splice(activeValues.value.indexOf(props.id), 1);
} else {
// -->
activeValues.value.push(props.id);
}
emit("update:modelValue", (accordion ? activeValues.value[0] || null : activeValues.value));
emit(
"update:modelValue",
accordion ? activeValues.value[0] || null : activeValues.value
);
emit("change", props.id, !_isShow, activeValues.value);
}
};
</script>

View File

@ -1,86 +1,86 @@
<script lang="ts">
export default {
name: 'ColorBox',
}
name: "ColorBox",
};
</script>
<script setup lang="ts">
import { Nullable } from '../type'
import { computed, onMounted, ref } from 'vue'
import { HSBToHEX, RGBSTo, RGBToHSB } from './colorUtil'
import ColorPicker from './ColorPicker.vue'
import { usePosition } from '@layui/hooks-vue'
import { Nullable } from "../type";
import { computed, onMounted, ref } from "vue";
import { HSBToHEX, RGBSTo, RGBToHSB } from "./colorUtil";
import ColorPicker from "./ColorPicker.vue";
import { usePosition } from "@layui/hooks-vue";
interface BoxProps {
color?: string
size?: Nullable<string>
alpha?: boolean
format?: 'hex' | 'rgb'
predefine?: boolean
colors?: string[]
color?: string;
size?: Nullable<string>;
alpha?: boolean;
format?: "hex" | "rgb";
predefine?: boolean;
colors?: string[];
}
const colorBoxProps = withDefaults(defineProps<BoxProps>(), {
color: '',
color: "",
size: () => null,
alpha: false,
format: 'hex',
format: "hex",
predefine: false,
colors: () => [
//
'#009688',
'#5FB878',
'#1E9FFF',
'#FF5722',
'#FFB800',
'#01AAED',
'#999',
'#c00',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'rgb(0, 186, 189)',
'rgb(255, 120, 0)',
'rgb(250, 212, 0)',
'#393D49',
'rgba(0,0,0,.5)',
'rgba(255, 69, 0, 0.68)',
'rgba(144, 240, 144, 0.5)',
'rgba(31, 147, 255, 0.73)',
"#009688",
"#5FB878",
"#1E9FFF",
"#FF5722",
"#FFB800",
"#01AAED",
"#999",
"#c00",
"#ff8c00",
"#ffd700",
"#90ee90",
"#00ced1",
"#1e90ff",
"#c71585",
"rgb(0, 186, 189)",
"rgb(255, 120, 0)",
"rgb(250, 212, 0)",
"#393D49",
"rgba(0,0,0,.5)",
"rgba(255, 69, 0, 0.68)",
"rgba(144, 240, 144, 0.5)",
"rgba(31, 147, 255, 0.73)",
],
})
});
const triggerSpanStyle = computed(() => {
let bgstr = ''
let bgstr = "";
if (colorBoxProps.color) {
bgstr = colorBoxProps.color
bgstr = colorBoxProps.color;
if ((colorBoxProps.color.match(/[0-9]{1,3}/g) || []).length > 3) {
//
if (!(colorBoxProps.alpha && colorBoxProps.format == 'rgb')) {
bgstr = '#' + HSBToHEX(RGBToHSB(RGBSTo(colorBoxProps.color)))
if (!(colorBoxProps.alpha && colorBoxProps.format == "rgb")) {
bgstr = "#" + HSBToHEX(RGBToHSB(RGBSTo(colorBoxProps.color)));
}
}
}
return {
background: bgstr,
}
})
};
});
const colorPickerWrapper = computed(() => {
return colorBoxProps.size ? `layui-colorpicker-${colorBoxProps.size}` : ''
})
return colorBoxProps.size ? `layui-colorpicker-${colorBoxProps.size}` : "";
});
const colorBoxRefEl = ref<HTMLElement | null>(null)
const colorPickerRefEl = ref<HTMLElement | null>(null)
const colorBoxRefEl = ref<HTMLElement | null>(null);
const colorPickerRefEl = ref<HTMLElement | null>(null);
onMounted(() => {
console.log('colorPickerRefEl =>>>', colorPickerRefEl.value.teleportRefEl)
usePosition(colorBoxRefEl.value, colorPickerRefEl.value.teleportRefEl)
})
console.log("colorPickerRefEl =>>>", colorPickerRefEl.value.teleportRefEl);
usePosition(colorBoxRefEl.value, colorPickerRefEl.value.teleportRefEl);
});
</script>
<template>
<div ref="colorBoxRefEl" class="layui-unselect layui-colorpicker">

View File

@ -1,23 +1,23 @@
<script lang="ts">
export default {
name: 'ColorPicker',
}
name: "ColorPicker",
};
</script>
<script setup lang="ts">
import { ref } from 'vue'
import { ref } from "vue";
interface CProps {
visible: boolean
alpha: boolean
predefine: boolean
visible: boolean;
alpha: boolean;
predefine: boolean;
}
const props = defineProps<CProps>()
const props = defineProps<CProps>();
const domRefEl = ref<HTMLElement | null>(null)
const domRefEl = ref<HTMLElement | null>(null);
defineExpose({
teleportRefEl: domRefEl,
})
});
</script>
<template>
<teleport to="body">

View File

@ -1,54 +1,54 @@
<script lang="ts">
export default {
name: 'LayColorPicker',
}
name: "LayColorPicker",
};
</script>
<script lang="ts" setup>
import { Nullable } from '/@src/module/type'
import ColorBox from './ColorBox.vue'
import { Nullable } from "/@src/module/type";
import ColorBox from "./ColorBox.vue";
interface ColorPickerProps {
color?: string
size?: Nullable<string>
alpha?: boolean
format?: 'hex' | 'rgb'
predefine?: boolean
colors?: string[]
color?: string;
size?: Nullable<string>;
alpha?: boolean;
format?: "hex" | "rgb";
predefine?: boolean;
colors?: string[];
}
const colorPickerProps = withDefaults(defineProps<ColorPickerProps>(), {
color: '',
color: "",
size: () => null,
alpha: false,
format: 'hex',
format: "hex",
predefine: false,
colors: () => [
//
'#009688',
'#5FB878',
'#1E9FFF',
'#FF5722',
'#FFB800',
'#01AAED',
'#999',
'#c00',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'rgb(0, 186, 189)',
'rgb(255, 120, 0)',
'rgb(250, 212, 0)',
'#393D49',
'rgba(0,0,0,.5)',
'rgba(255, 69, 0, 0.68)',
'rgba(144, 240, 144, 0.5)',
'rgba(31, 147, 255, 0.73)',
"#009688",
"#5FB878",
"#1E9FFF",
"#FF5722",
"#FFB800",
"#01AAED",
"#999",
"#c00",
"#ff8c00",
"#ffd700",
"#90ee90",
"#00ced1",
"#1e90ff",
"#c71585",
"rgb(0, 186, 189)",
"rgb(255, 120, 0)",
"rgb(250, 212, 0)",
"#393D49",
"rgba(0,0,0,.5)",
"rgba(255, 69, 0, 0.68)",
"rgba(144, 240, 144, 0.5)",
"rgba(31, 147, 255, 0.73)",
],
})
});
</script>
<template>

View File

@ -1,12 +1,12 @@
.layui-container {
position: relative;
margin: 0 auto;
padding: 0 15px;
box-sizing: border-box;
position: relative;
margin: 0 auto;
padding: 0 15px;
box-sizing: border-box;
}
.layui-fluid {
position: relative;
margin: 0 auto;
padding: 0 15px;
}
position: relative;
margin: 0 auto;
padding: 0 15px;
}

View File

@ -1,26 +1,28 @@
<script lang="ts">
export default {
name: "LayContainer"
}
name: "LayContainer",
};
</script>
<script setup lang="ts">
import { computed, defineProps } from 'vue'
import "./index.less"
import { computed, defineProps } from "vue";
import "./index.less";
export interface LayContainerProps {
fluid?: boolean
fluid?: boolean;
}
const props = withDefaults(defineProps<LayContainerProps>(), {
fluid: false
fluid: false,
});
const classes = computed(() => props.fluid ? 'layui-fluid' : 'layui-container')
const classes = computed(() =>
props.fluid ? "layui-fluid" : "layui-container"
);
</script>
<template>
<div :class="classes">
<slot />
</div>
</template>
</template>

View File

@ -1,45 +1,45 @@
<script lang="ts">
export default {
name: "LayDropdown"
}
name: "LayDropdown",
};
</script>
<script setup lang="ts">
import { defineProps, provide, ref, watch } from 'vue'
import { useClickOutside } from '@layui/hooks-vue'
import { defineProps, provide, ref, watch } from "vue";
import { useClickOutside } from "@layui/hooks-vue";
const dropdownRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(dropdownRef)
const dropdownRef = ref<null | HTMLElement>(null);
const isClickOutside = useClickOutside(dropdownRef);
export interface LayDropdownProps {
trigger?: string
trigger?: string;
}
const props = withDefaults(defineProps<LayDropdownProps>(),{
trigger: 'click',
})
const props = withDefaults(defineProps<LayDropdownProps>(), {
trigger: "click",
});
const openState = ref(false)
const openState = ref(false);
const open = function () {
openState.value = true
}
openState.value = true;
};
const hide = function () {
openState.value = false
}
openState.value = false;
};
const toggle = function () {
openState.value = !openState.value
}
openState.value = !openState.value;
};
watch(isClickOutside, () => {
if (isClickOutside.value) {
openState.value = false
openState.value = false;
}
})
});
provide('openState', openState)
provide("openState", openState);
defineExpose({ open, hide, toggle });
</script>
@ -76,4 +76,4 @@ defineExpose({ open, hide, toggle });
</ul>
</dl>
</div>
</template>
</template>

View File

@ -7,11 +7,11 @@
</template>
<script setup name="LayDropdownItem" lang="ts">
import { inject, Ref } from 'vue'
import { inject, Ref } from "vue";
const openState: Ref<boolean> = inject('openState') as Ref<boolean>
const openState: Ref<boolean> = inject("openState") as Ref<boolean>;
const click = function () {
openState.value = false
}
openState.value = false;
};
</script>

View File

@ -1,20 +1,20 @@
.layui-empty {
margin: 0 8px;
font-size: 14px;
line-height: 22px;
text-align: center;
margin: 0 8px;
font-size: 14px;
line-height: 22px;
text-align: center;
}
.layui-empty-image {
height: 100px;
margin-bottom: 8px;
height: 100px;
margin-bottom: 8px;
}
.layui-empty-image img {
height: 100%;
margin: auto;
height: 100%;
margin: auto;
}
.layui-empty-description {
margin: 0;
}
margin: 0;
}

View File

@ -27,4 +27,4 @@ const props = withDefaults(defineProps<LayEmptyProps>(), {
{{ description }}
</div>
</div>
</template>
</template>

View File

@ -1,5 +1,4 @@
<template>
<fieldset v-if="slot.default" class="layui-elem-field">
<legend>{{ title }}</legend>
<div class="layui-field-box">
@ -8,18 +7,18 @@
</fieldset>
<fieldset v-else class="layui-elem-field layui-field-title">
<legend><a name="docend">{{title}}</a></legend>
<legend>
<a name="docend">{{ title }}</a>
</legend>
</fieldset>
</template>
<script setup name="LayField" lang="ts">
import { defineProps, useSlots } from 'vue'
import { defineProps, useSlots } from "vue";
const slot = useSlots()
const slot = useSlots();
const props =
defineProps<{
title?: string
}>()
const props = defineProps<{
title?: string;
}>();
</script>

View File

@ -1,3 +1,3 @@
.layui-footer {
box-sizing: border-box;
}
box-sizing: border-box;
}

View File

@ -1,15 +1,15 @@
<script lang="ts">
export default {
name: 'LayFooter',
}
name: "LayFooter",
};
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>
<div class="layui-footer">
<slot />
</div>
</template>
</template>

View File

@ -5,136 +5,158 @@
</template>
<script lang="ts">
export default{
name: 'LayForm'
}
export default {
name: "LayForm",
};
</script>
<script setup lang="ts">
import { toRefs, provide,reactive, onMounted } from "vue"
import { Rule, ValidateError, ValidateMessages } from "async-validator"
import {layFormKey, LayFormItemContext, FormCallback, modelType} from "../type/form"
import { toRefs, provide, reactive, onMounted } from "vue";
import { Rule, ValidateError, ValidateMessages } from "async-validator";
import {
layFormKey,
LayFormItemContext,
FormCallback,
modelType,
} from "../type/form";
const props = withDefaults(
defineProps<{
model?: modelType
required?: boolean,
rules?: Rule,
initValidate?: boolean,
requiredIcons?: string,
requiredErrorMessage?: string,
validateMessage?: ValidateMessages,
useCN?: boolean
model?: modelType;
required?: boolean;
rules?: Rule;
initValidate?: boolean;
requiredIcons?: string;
requiredErrorMessage?: string;
validateMessage?: ValidateMessages;
useCN?: boolean;
}>(),
{
model: function(){
return {}
model: function () {
return {};
},
useCN : true,
requiredIcons : '',
initValidate : false
useCN: true,
requiredIcons: "",
initValidate: false,
}
)
);
const formItems : LayFormItemContext[] = [];
const formItemMap : {[key:string]:LayFormItemContext} = {};
const formItems: LayFormItemContext[] = [];
const formItemMap: { [key: string]: LayFormItemContext } = {};
const emit = defineEmits(['submit'])
const emit = defineEmits(["submit"]);
//
onMounted(()=>{
props.initValidate && validate()?.catch(err => {});
})
onMounted(() => {
props.initValidate && validate()?.catch((err) => {});
});
//
const submit = function () {
let _isValidate = false;
validate((isValidate, model, errors) => {
_isValidate = isValidate as boolean;
emit('submit', isValidate, model, errors);
emit("submit", isValidate, model, errors);
});
//
return _isValidate;
}
};
/**
* 校验表单数据
* @param fields 需要校验的表单字段(string|string[]); 该字段如果为function, 则默认为回调函数校验全部字段;
* @param callback 校验表单之后的回调函数
**/
const validate = function(fields?: string|string[]|FormCallback|null, callback?: FormCallback | null){
const validate = function (
fields?: string | string[] | FormCallback | null,
callback?: FormCallback | null
) {
//
let validateItems : LayFormItemContext[] = formItems;
if (typeof fields === 'function') {
let validateItems: LayFormItemContext[] = formItems;
if (typeof fields === "function") {
callback = fields;
} else if (typeof fields === 'string' || (Array.isArray(fields) && fields.length > 0)) {
} else if (
typeof fields === "string" ||
(Array.isArray(fields) && fields.length > 0)
) {
validateItems = [];
const validateFields = !fields ? [] : ([] as string[]).concat(fields);
validateFields.forEach(field => formItemMap[field] && validateItems.push(formItemMap[field]));
validateFields.forEach(
(field) => formItemMap[field] && validateItems.push(formItemMap[field])
);
}
//
let errorsArrs: ValidateError[] = [];
validateItems.forEach(filed => {
filed.validate((errors, _fields)=>{
validateItems.forEach((filed) => {
filed.validate((errors, _fields) => {
errorsArrs = errorsArrs.concat(errors as ValidateError[]);
});
});
const isValidate = errorsArrs.length === 0;
//
if (typeof callback === 'function') {
isValidate ? callback(true, props.model, null) : callback(false, props.model, errorsArrs);
if (typeof callback === "function") {
isValidate
? callback(true, props.model, null)
: callback(false, props.model, errorsArrs);
return null;
}
// Promise
return new Promise((resolve, reject) => {
const callbackParams = {
isValidate,
model : props.model,
errors: isValidate ? null : errorsArrs
isValidate,
model: props.model,
errors: isValidate ? null : errorsArrs,
};
callbackParams.isValidate ? resolve(callbackParams) : reject(callbackParams);
callbackParams.isValidate
? resolve(callbackParams)
: reject(callbackParams);
});
}
};
/**
* 清除校验
* @param fields 需要进行清除校验的表单字段(string|string[]); 该字段如果为null, 则默认为全部字段清除校验;
**/
const clearValidate = function(fields?: string | string[]){
const clearValidate = function (fields?: string | string[]) {
const clearFields = !fields ? [] : ([] as string[]).concat(fields);
if (clearFields.length === 0) {
formItems.forEach(filed => filed.clearValidate());
formItems.forEach((filed) => filed.clearValidate());
} else {
clearFields.forEach(field => formItemMap[field] && formItemMap[field].clearValidate());
clearFields.forEach(
(field) => formItemMap[field] && formItemMap[field].clearValidate()
);
}
}
};
/**
* 重置表单所有值
**/
const reset = function(){
const reset = function () {
for (const key in props.model) {
props.model[key] = null;
}
//
setTimeout(()=>validate()?.catch(err => {}), 0);
}
setTimeout(() => validate()?.catch((err) => {}), 0);
};
//
const addField = function(item : LayFormItemContext) {
const addField = function (item: LayFormItemContext) {
formItems.push(item);
formItemMap[item.prop as string] = item;
}
};
defineExpose({validate, clearValidate, reset});
defineExpose({ validate, clearValidate, reset });
provide(layFormKey, reactive({
formItems,
addField,
clearValidate,
validate,
...toRefs(props)
}));
provide(
layFormKey,
reactive({
formItems,
addField,
clearValidate,
validate,
...toRefs(props),
})
);
</script>

View File

@ -1,39 +1,38 @@
@error_color : red;
@error_color: red;
.layui-required{
color: @error_color;
font-size: 12px;
line-height: 1;
.layui-required {
color: @error_color;
font-size: 12px;
line-height: 1;
}
.layui-form .layui-form-item{
.layui-input-block
,.layui-input-inline{
.layui-form-danger {
border-color: #ff5722 !important;
}
.layui-form .layui-form-item {
.layui-input-block,
.layui-input-inline {
.layui-form-danger {
border-color: #ff5722 !important;
}
}
}
.layui-error-message {
color: @error_color;
font-size: 12px;
line-height: 1;
padding-top: 2px;
position: absolute;
top: 100%;
left: 0;
color: @error_color;
font-size: 12px;
line-height: 1;
padding-top: 2px;
position: absolute;
top: 100%;
left: 0;
}
.layui-error-message-anim {
-ms-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-animation: layui-top-show-anim 0.3s ease 1;
animation: layui-top-show-anim 0.3s ease 1;
-ms-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-animation: layui-top-show-anim 0.3s ease 1;
animation: layui-top-show-anim 0.3s ease 1;
}
@keyframes layui-top-show-anim {
0% {
opacity: 0.3;
@ -44,4 +43,4 @@
opacity: 1;
transform: rotateX(0);
}
}
}

View File

@ -1,140 +1,194 @@
<template>
<div class="layui-form-item" ref="formItemRef">
<label class="layui-form-label">
<span v-if="props.prop &&isRequired" :class="['layui-required', 'layui-icon'].concat(layForm.requiredIcons??'')">
<slot name="required" :props="{...props, model: layForm.model}">{{layForm.requiredIcons? '' : '*'}}</slot>
<span
v-if="props.prop && isRequired"
:class="
['layui-required', 'layui-icon'].concat(layForm.requiredIcons ?? '')
"
>
<slot name="required" :props="{ ...props, model: layForm.model }">{{
layForm.requiredIcons ? "" : "*"
}}</slot>
</span>
<slot name="label" :props="{...props, model: layForm.model}">
<slot name="label" :props="{ ...props, model: layForm.model }">
{{ label }}
</slot>
</label>
<div :class="[mode ? 'layui-input-' + mode : '']">
<div ref="slotParent">
<slot :props="{...props, model: layForm.model}"/>
<slot :props="{ ...props, model: layForm.model }" />
</div>
<span v-if="errorStatus" :class="['layui-error-message', {'layui-error-message-anim': errorStatus}]">{{errorMsg}}</span>
<span
v-if="errorStatus"
:class="[
'layui-error-message',
{ 'layui-error-message-anim': errorStatus },
]"
>{{ errorMsg }}</span
>
</div>
</div>
</template>
<script setup name="LayFormItem" lang="ts">
import "./index.less";
import { defineProps, inject, withDefaults, ref, reactive, toRefs, onMounted, computed, watch} from 'vue'
import {layFormKey, LayFormContext, LayFormItemContext, FieldValidateError} from "../type/form"
import Schema, { Rule, RuleItem, Rules, ValidateCallback, ValidateError, ValidateMessages} from 'async-validator';
import cnValidateMessage from './cnValidateMessage';
import {
defineProps,
inject,
withDefaults,
ref,
reactive,
toRefs,
onMounted,
computed,
watch,
} from "vue";
import {
layFormKey,
LayFormContext,
LayFormItemContext,
FieldValidateError,
} from "../type/form";
import Schema, {
Rule,
RuleItem,
Rules,
ValidateCallback,
ValidateError,
ValidateMessages,
} from "async-validator";
import cnValidateMessage from "./cnValidateMessage";
const props = withDefaults(
defineProps<{
prop?: string
mode?: string
label?: string
errorMessage?: string
rules?: Rule
required?: boolean
prop?: string;
mode?: string;
label?: string;
errorMessage?: string;
rules?: Rule;
required?: boolean;
}>(),
{
mode: 'block'
mode: "block",
}
)
);
const layForm = inject(layFormKey, {} as LayFormContext)
const formItemRef = ref<HTMLDivElement>()
const slotParent = ref<HTMLDivElement>()
const layForm = inject(layFormKey, {} as LayFormContext);
const formItemRef = ref<HTMLDivElement>();
const slotParent = ref<HTMLDivElement>();
//
const isRequired = computed(()=>{
const isRequired = computed(() => {
return props.required || layForm.required;
})
});
//
const ruleItems = computed(()=>{
const ruleItems = computed(() => {
const prop = props.prop;
if (!prop) {
return {};
}
let rulesArrs : RuleItem[] = [];
let rulesArrs: RuleItem[] = [];
if (isRequired.value) {
rulesArrs.push({required: true});
rulesArrs.push({ required: true });
}
if (props.rules) {
rulesArrs = rulesArrs.concat((props.rules as RuleItem | RuleItem[]));
rulesArrs = rulesArrs.concat(props.rules as RuleItem | RuleItem[]);
}
if (layForm.rules && layForm.rules[prop]) {
rulesArrs = rulesArrs.concat((layForm.rules[prop] as RuleItem | RuleItem[]));
rulesArrs = rulesArrs.concat(layForm.rules[prop] as RuleItem | RuleItem[]);
}
return rulesArrs;
});
//
const filedValue = computed(()=> props.prop ? layForm.model[props.prop] : undefined);
watch(()=>filedValue.value, (val)=> validate(), {deep: true});
const filedValue = computed(() =>
props.prop ? layForm.model[props.prop] : undefined
);
watch(
() => filedValue.value,
(val) => validate(),
{ deep: true }
);
//
const errorStatus = ref(false);
const errorMsg = ref();
//
const validate = (callback ?: ValidateCallback)=> {
const validate = (callback?: ValidateCallback) => {
if (props.prop && (ruleItems.value as RuleItem[]).length > 0) {
//
const descriptor : Rules = {};
descriptor[layForm.useCN? (props.label||props.prop ): props.prop] = ruleItems.value;
const descriptor: Rules = {};
descriptor[layForm.useCN ? props.label || props.prop : props.prop] =
ruleItems.value;
const validator = new Schema(descriptor);
let model : {[key : string]:any} = {};
let model: { [key: string]: any } = {};
let validateMessage = null;
// 使
if (layForm.useCN) {
validateMessage = Object.assign({}, cnValidateMessage, layForm.validateMessage);
model[props.label||props.prop] = filedValue.value;
validateMessage = Object.assign(
{},
cnValidateMessage,
layForm.validateMessage
);
model[props.label || props.prop] = filedValue.value;
} else {
layForm.validateMessage && (validateMessage = layForm.validateMessage);
layForm.validateMessage && (validateMessage = layForm.validateMessage);
model[props.prop] = filedValue.value;
}
//
layForm.requiredErrorMessage && (validateMessage = Object.assign(validateMessage, {required : layForm.requiredErrorMessage}));
layForm.requiredErrorMessage &&
(validateMessage = Object.assign(validateMessage, {
required: layForm.requiredErrorMessage,
}));
validateMessage && validator.messages(validateMessage);
//
validator.validate(model, (errors, fields) => {
errorStatus.value = errors !== null && errors.length > 0;
const slotParentDiv = slotParent.value as HTMLDivElement;
if (errorStatus.value) {
const _errors = (errors as FieldValidateError[]);
const _errors = errors as FieldValidateError[];
// ,FieldValidateError
layForm.useCN && _errors.forEach(error => {
error.label = props.label;
error.field = props.prop;
})
errorMsg.value = props.errorMessage??_errors[0].message;
slotParentDiv.childElementCount > 0 && slotParentDiv.firstElementChild?.classList.add('layui-form-danger');
layForm.useCN &&
_errors.forEach((error) => {
error.label = props.label;
error.field = props.prop;
});
errorMsg.value = props.errorMessage ?? _errors[0].message;
slotParentDiv.childElementCount > 0 &&
slotParentDiv.firstElementChild?.classList.add("layui-form-danger");
callback && callback(_errors, fields);
} else {
clearValidate();
}
});
}
}
};
//
const clearValidate = ()=> {
const clearValidate = () => {
errorStatus.value = false;
errorMsg.value = '';
errorMsg.value = "";
const slotParentDiv = slotParent.value as HTMLDivElement;
slotParentDiv.childElementCount > 0 && slotParentDiv.firstElementChild?.classList.remove('layui-form-danger');
}
slotParentDiv.childElementCount > 0 &&
slotParentDiv.firstElementChild?.classList.remove("layui-form-danger");
};
defineExpose({validate, clearValidate});
defineExpose({ validate, clearValidate });
onMounted(()=>{
onMounted(() => {
if (props.prop) {
layForm.addField(reactive({
...toRefs(props),
$el: formItemRef,
validate,
clearValidate
}) as LayFormItemContext);
layForm.addField(
reactive({
...toRefs(props),
$el: formItemRef,
validate,
clearValidate,
}) as LayFormItemContext
);
}
})
});
</script>

View File

@ -1,4 +1,4 @@
.layui-header {
box-sizing: border-box;
height: 60px;
}
box-sizing: border-box;
height: 60px;
}

View File

@ -12,4 +12,4 @@ import "./index.less";
<div class="layui-header">
<slot />
</div>
</template>
</template>

View File

@ -1,9 +1,7 @@
<template>
<lay-dropdown ref="dropdownRef">
<div
class="
layui-inline layui-border-box layui-iconpicker layui-iconpicker-split
"
class="layui-inline layui-border-box layui-iconpicker layui-iconpicker-split"
>
<div class="layui-inline layui-iconpicker-main">
<i class="layui-inline layui-icon" :class="[selectedIcon]" />
@ -82,118 +80,118 @@
</template>
<script setup name="LayIconPicker" lang="ts">
import { defineProps, Ref, ref } from 'vue'
import { LayIconList as icons } from "@layui/icons-vue"
import { defineProps, Ref, ref } from "vue";
import { LayIconList as icons } from "@layui/icons-vue";
export interface LayIconPickerProps {
page?: boolean,
modelValue?: string,
showSearch?: boolean
page?: boolean;
modelValue?: string;
showSearch?: boolean;
}
const props = withDefaults(defineProps<LayIconPickerProps>(),{
modelValue: 'layui-icon-face-smile',
page: false,
})
const props = withDefaults(defineProps<LayIconPickerProps>(), {
modelValue: "layui-icon-face-smile",
page: false,
});
const dropdownRef = ref<null | HTMLElement>(null);
const emit = defineEmits(['update:modelValue'])
const emit = defineEmits(["update:modelValue"]);
const selectedIcon: Ref<string> = ref(props.modelValue as string)
const selectedIcon: Ref<string> = ref(props.modelValue as string);
const selectIcon = function (icon: string) {
emit('update:modelValue', icon)
selectedIcon.value = icon
emit("update:modelValue", icon);
selectedIcon.value = icon;
// @ts-ignore
dropdownRef.value.hide()
}
dropdownRef.value.hide();
};
const icones: Ref = ref([])
const icones: Ref = ref([]);
const total = ref(icons.length)
const totalPage = ref(total.value / 12)
const currentPage: Ref = ref(1)
const total = ref(icons.length);
const totalPage = ref(total.value / 12);
const currentPage: Ref = ref(1);
if (props.page) {
icones.value = icons.slice(0, 12)
icones.value = icons.slice(0, 12);
} else {
icones.value = icons
icones.value = icons;
}
const next = function () {
if (currentPage.value === totalPage.value) {
return
return;
}
currentPage.value = currentPage.value + 1
const start = (currentPage.value - 1) * 12
const end = start + 12
icones.value = icons.slice(start, end)
}
currentPage.value = currentPage.value + 1;
const start = (currentPage.value - 1) * 12;
const end = start + 12;
icones.value = icons.slice(start, end);
};
const prev = function () {
if (currentPage.value === 1) {
return
return;
}
currentPage.value = currentPage.value - 1
const start = (currentPage.value - 1) * 12
const end = start + 12
icones.value = icons.slice(start, end)
}
currentPage.value = currentPage.value - 1;
const start = (currentPage.value - 1) * 12;
const end = start + 12;
icones.value = icons.slice(start, end);
};
const search = function (e: any) {
var text = e.target.value
currentPage.value = 1
const start = (currentPage.value - 1) * 12
const end = start + 12
if (text === '') {
var text = e.target.value;
currentPage.value = 1;
const start = (currentPage.value - 1) * 12;
const end = start + 12;
if (text === "") {
if (props.page) {
icones.value = icons.slice(start, end)
total.value = icons.length
totalPage.value = Math.ceil(icons.length / 12)
icones.value = icons.slice(start, end);
total.value = icons.length;
totalPage.value = Math.ceil(icons.length / 12);
} else {
icones.value = icons
icones.value = icons;
}
} else {
if (props.page) {
icones.value = searchList(text, icons).slice(start, end)
total.value = searchList(text, icons).length
totalPage.value = Math.ceil(searchList(text, icons).length / 12)
icones.value = searchList(text, icons).slice(start, end);
total.value = searchList(text, icons).length;
totalPage.value = Math.ceil(searchList(text, icons).length / 12);
} else {
icones.value = searchList(text, icons)
icones.value = searchList(text, icons);
}
}
}
};
const searchList = function (str: string, container: any) {
var newList = []
var startChar = str.charAt(0)
var strLen = str.length
var newList = [];
var startChar = str.charAt(0);
var strLen = str.length;
for (var i = 0; i < container.length; i++) {
var obj = container[i]
var isMatch = false
var obj = container[i];
var isMatch = false;
for (var p in obj) {
if (typeof obj[p] == 'function') {
obj[p]()
if (typeof obj[p] == "function") {
obj[p]();
} else {
var curItem = ''
var curItem = "";
if (obj[p] != null) {
curItem = obj[p]
curItem = obj[p];
}
for (var j = 0; j < curItem.length; j++) {
if (curItem.charAt(j) == startChar) {
if (curItem.substring(j).substring(0, strLen) == str) {
isMatch = true
break
isMatch = true;
break;
}
}
}
}
}
if (isMatch) {
newList.push(obj)
newList.push(obj);
}
}
return newList
}
return newList;
};
</script>

View File

@ -41,5 +41,4 @@ const onFocus = function (event: FocusEvent) {
const onBlur = function () {
emit("blur");
};
</script>

View File

@ -13,11 +13,11 @@
@xs-wdith: 120px;
@xs-right: 12px;
.set-size(@width, @size, @right-size){
&{
.set-size(@width, @size, @right-size) {
& {
height: @size;
width: @width;
.layui-input{
.layui-input {
height: @size;
line-height: @size;
padding: 0 @size;
@ -27,22 +27,22 @@
height: @size;
line-height: @size;
}
&[position=right]{
.layui-input{
&[position="right"] {
.layui-input {
padding: 0 @size 0 0;
}
.layui-control-btn {
height: @right-size;
line-height: @right-size;
}
.layui-subtraction-btn{
.layui-subtraction-btn {
top: @right-size - 1;
}
}
}
}
.layui-input-number{
.layui-input-number {
position: relative;
display: inline-block;
box-sizing: border-box;
@ -52,7 +52,7 @@
overflow: hidden;
.set-size(@lg-wdith, @lg, @lg-right);
margin-left: 5px;
.layui-input{
.layui-input {
text-align: center;
border: 0;
}
@ -66,17 +66,17 @@
padding: 0;
text-align: center;
top: 0;
&:hover{
&:hover {
color: @hover-border-color;
}
&.layui-subtraction-btn{
&.layui-subtraction-btn {
border-right-width: 1px;
}
&.layui-addition-btn{
&.layui-addition-btn {
border-left-width: 1px;
right: 0;
}
.layui-icon{
.layui-icon {
padding: 0px;
}
}
@ -87,31 +87,30 @@
}
/* 火狐--去掉自带的控制按钮 */
input.layui-input[type="number"]{
input.layui-input[type="number"] {
-moz-appearance: textfield;
}
&[position=right]{
.layui-subtraction-btn{
&[position="right"] {
.layui-subtraction-btn {
right: 0;
border-right-width: 0px;
border-left-width: 1px;
}
.layui-addition-btn{
.layui-addition-btn {
border-bottom-width: 1px;
}
}
&[size=md] {
.set-size(@md-wdith,@md, @md-right)
&[size="md"] {
.set-size(@md-wdith,@md, @md-right);
}
&[size=sm] {
.set-size(@sm-wdith, @sm, @sm-right)
&[size="sm"] {
.set-size(@sm-wdith, @sm, @sm-right);
}
&[size=xs] {
.set-size(@xs-wdith, @xs, @xs-right)
&[size="xs"] {
.set-size(@xs-wdith, @xs, @xs-right);
}
}
}

View File

@ -9,7 +9,11 @@
:disabled="minControl"
class="layui-control-btn layui-subtraction-btn"
>
<lay-icon :type="position==='right' ? 'layui-icon-down' : 'layui-icon-subtraction'"></lay-icon>
<lay-icon
:type="
position === 'right' ? 'layui-icon-down' : 'layui-icon-subtraction'
"
></lay-icon>
</lay-button>
<div class="layui-input-number-input">
<lay-input
@ -29,15 +33,17 @@
:disabled="maxControl"
class="layui-control-btn layui-addition-btn"
>
<lay-icon :type="position==='right' ? 'layui-icon-up' : 'layui-icon-addition'"></lay-icon>
<lay-icon
:type="position === 'right' ? 'layui-icon-up' : 'layui-icon-addition'"
></lay-icon>
</lay-button>
</div>
</template>
<script lang="ts">
export default {
name: "LayInputNumber",
};
export default {
name: "LayInputNumber",
};
</script>
<script setup lang="ts">
@ -94,11 +100,14 @@ watch(num, (val) => {
}
});
watch(()=>props.modelValue, (val) => {
if (val !== num.value) {
num.value = props.modelValue;
watch(
() => props.modelValue,
(val) => {
if (val !== num.value) {
num.value = props.modelValue;
}
}
});
);
const tempValue = ref(0);
let timer: any = 0;

View File

@ -1,12 +1,12 @@
.layui-layout {
display: flex;
flex: 1;
flex-basis: auto;
height: 100%;
width: 100%;
box-sizing: border-box;
display: flex;
flex: 1;
flex-basis: auto;
height: 100%;
width: 100%;
box-sizing: border-box;
}
.layui-layout-vertical {
flex-direction: column;
}
flex-direction: column;
}

View File

@ -38,4 +38,4 @@ const classes = computed(() => {
<section :class="classes">
<slot />
</section>
</template>
</template>

View File

@ -3,9 +3,9 @@
</template>
<script setup name="LayLine" lang="ts">
import { defineProps } from 'vue'
import { defineProps } from "vue";
const props = defineProps<{
theme?: string
}>()
theme?: string;
}>();
</script>

View File

@ -2,25 +2,24 @@
<dd :class="[selectedKey === id ? 'layui-this' : '']" @click="selectHandle()">
<slot v-if="slots.title" name="title"></slot>
<a v-else href="javascript:void(0)">
{{title}}
{{ title }}
</a>
</dd>
</template>
<script setup name="LayMenuChildItem" lang="ts">
import { defineProps, inject, Ref, useSlots } from 'vue'
import { defineProps, inject, Ref, useSlots } from "vue";
const slots = useSlots()
const slots = useSlots();
const props =
defineProps<{
id: string
title: string
}>()
const props = defineProps<{
id: string;
title: string;
}>();
const selectedKey: Ref<string> = inject('selectedKey') as Ref<string>
const selectedKey: Ref<string> = inject("selectedKey") as Ref<string>;
const selectHandle = function () {
selectedKey.value = props.id
}
selectedKey.value = props.id;
};
</script>

View File

@ -33,29 +33,27 @@
</template>
<script setup name="LayMenuItem" lang="ts">
import { defineProps, inject, Ref, ref, useSlots } from 'vue'
const slots = useSlots()
import { defineProps, inject, Ref, ref, useSlots } from "vue";
const slots = useSlots();
const props =
defineProps<{
id: string
title: string
}>()
const props = defineProps<{
id: string;
title: string;
}>();
const isTree = inject('isTree')
const selectedKey: Ref<string> = inject('selectedKey') as Ref<string>
const openKeys: Ref<string[]> = inject('openKeys') as Ref<string[]>
const isTree = inject("isTree");
const selectedKey: Ref<string> = inject("selectedKey") as Ref<string>;
const openKeys: Ref<string[]> = inject("openKeys") as Ref<string[]>;
const openHandle = function () {
if(openKeys.value.includes(props.id)) {
openKeys.value.splice(openKeys.value.indexOf(props.id),1)
if (openKeys.value.includes(props.id)) {
openKeys.value.splice(openKeys.value.indexOf(props.id), 1);
} else {
openKeys.value.push(props.id)
openKeys.value.push(props.id);
}
}
};
const selectHandle = function () {
selectedKey.value = props.id
}
selectedKey.value = props.id;
};
</script>

View File

@ -53,25 +53,25 @@
</template>
<script setup name="LayPage" lang="ts">
import { defineProps, Ref, ref, watch, useSlots } from 'vue'
import { defineProps, Ref, ref, watch, useSlots } from "vue";
const slots = useSlots()
const slots = useSlots();
const props = withDefaults(
defineProps<{
total: number
limit: number
theme?: string
showPage?: boolean | string
showSkip?: boolean | string
showCount?: boolean | string
showLimit?: boolean | string
showInput?: boolean | string
showRefresh?: boolean | string
total: number;
limit: number;
theme?: string;
showPage?: boolean | string;
showSkip?: boolean | string;
showCount?: boolean | string;
showLimit?: boolean | string;
showInput?: boolean | string;
showRefresh?: boolean | string;
}>(),
{
limit: 10,
theme: 'green',
theme: "green",
showPage: false,
showSkip: false,
showCount: false,
@ -79,44 +79,44 @@ const props = withDefaults(
showInput: false,
showRefresh: false,
}
)
);
const inlimit = ref(props.limit)
const totalPage = ref(Math.ceil(props.total / inlimit.value))
const currentPage: Ref<number> = ref(1)
const currentPageShow: Ref<number> = ref(currentPage.value)
const inlimit = ref(props.limit);
const totalPage = ref(Math.ceil(props.total / inlimit.value));
const currentPage: Ref<number> = ref(1);
const currentPageShow: Ref<number> = ref(currentPage.value);
const emit = defineEmits(['jump'])
const emit = defineEmits(["jump"]);
const prev = function () {
if (currentPage.value === 1) {
return
return;
}
currentPage.value--
}
currentPage.value--;
};
const next = function () {
if (currentPage.value === totalPage.value) {
return
return;
}
currentPage.value++
}
currentPage.value++;
};
const jump = function (page: number) {
currentPage.value = page
}
currentPage.value = page;
};
const jumpPage = function () {
currentPage.value = currentPageShow.value
}
currentPage.value = currentPageShow.value;
};
watch(inlimit, function () {
currentPage.value = 1
totalPage.value = Math.ceil(props.total / inlimit.value)
})
currentPage.value = 1;
totalPage.value = Math.ceil(props.total / inlimit.value);
});
watch(currentPage, function () {
currentPageShow.value = currentPage.value
emit('jump', { current: currentPage.value })
})
currentPageShow.value = currentPage.value;
emit("jump", { current: currentPage.value });
});
</script>

View File

@ -1,7 +1,7 @@
.layui-panel {
border-width: 1px;
border-style: solid;
border-radius: 2px;
background-color: #fff;
color: #666;
}
border-width: 1px;
border-style: solid;
border-radius: 2px;
background-color: #fff;
color: #666;
}

View File

@ -1,15 +1,15 @@
<script lang="ts">
export default {
name: "LayPanel"
}
name: "LayPanel",
};
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>
<div class="layui-panel">
<slot />
</div>
</template>
</template>

View File

@ -1,105 +1,132 @@
<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>
<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>
</template>
<script lang="ts">
const NAME = "LayPopper";
export default {
name: NAME
}
const NAME = "LayPopper";
export default {
name: NAME,
};
</script>
<script setup lang="ts">
import "./index.less";
import postionFns from "./calcPosition";
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>,
trigger ?: string,
enterable ?: boolean,
isDark ?: Ref<boolean>,
disabled ?: Ref<boolean>,
visible ?: Ref<boolean>,
isCanHide ?: Ref<boolean>,
updateVisible ?: Function
}>(),
{
enterable : true,
trigger : 'hover'
}
);
import "./index.less";
import postionFns from "./calcPosition";
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>;
trigger?: string;
enterable?: boolean;
isDark?: Ref<boolean>;
disabled?: Ref<boolean>;
visible?: Ref<boolean>;
isCanHide?: Ref<boolean>;
updateVisible?: Function;
}>(),
{
enterable: true,
trigger: "hover",
}
);
const EVENT_MAP : any = {
'hover' : ['mouseenter', null, 'mouseleave', false],
'click' : ['click', document, 'click', true]
}
const EVENT_MAP: any = {
hover: ["mouseenter", null, "mouseleave", false],
click: ["click", document, "click", true],
};
const triggerArr = EVENT_MAP[props.trigger];
if (!triggerArr) {
console.error(`${NAME} render error!cause: 'Trigger' must be 'hover/click' `)
}
const triggerArr = EVENT_MAP[props.trigger];
if (!triggerArr) {
console.error(`${NAME} render error!cause: 'Trigger' must be 'hover/click' `);
}
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 innerVisible = ref(props.visible??true);
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 innerVisible = ref(props.visible ?? true);
watch(innerVisible, (val)=>{
invokeShowPosistion();
props.updateVisible && props.updateVisible(val);
})
watch(innnerDisabled, (val)=>{
innerVisible.value = false;
})
watch(()=>props.content?.value, (val)=>{
innerVisible.value && invokeShowPosistion();
})
watch(innerVisible, (val) => {
invokeShowPosistion();
props.updateVisible && props.updateVisible(val);
});
watch(innnerDisabled, (val) => {
innerVisible.value = false;
});
watch(
() => props.content?.value,
(val) => {
innerVisible.value && invokeShowPosistion();
}
);
const doShow = function(){
if (!innnerDisabled.value) {
innerVisible.value = true;
}
}
const doShow = function () {
if (!innnerDisabled.value) {
innerVisible.value = true;
}
};
const doHidden = function(e : MouseEvent){
if ((checkTarget.value && props.el.contains(e.target)) || (props.enterable && popper.value.contains(e.target as Node))) return;
// style.value = {top: (-window.innerHeight) + 'px',left:0};
// popper.value.remove();
if (props.isCanHide?.value !== false) {
innerVisible.value = false;
}
innnerPosition.value = tempPosition.value;
}
const doHidden = function (e: MouseEvent) {
if (
(checkTarget.value && props.el.contains(e.target)) ||
(props.enterable && popper.value.contains(e.target as Node))
)
return;
// style.value = {top: (-window.innerHeight) + 'px',left:0};
// popper.value.remove();
if (props.isCanHide?.value !== false) {
innerVisible.value = false;
}
innnerPosition.value = tempPosition.value;
};
//
on(props.el, triggerArr[0], doShow);
on(triggerArr[1]??props.el, triggerArr[2], doHidden);
checkTarget.value = triggerArr[3];
//
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](props.el, popper.value, innnerPosition));
}
const invokeShowPosistion = function(){
if (innerVisible.value) {
popper.value.offsetWidth === 0 ? setTimeout(showPosistion, 0) : showPosistion();
//
setTimeout(()=>innerVisible.value && showPosistion(), 2);
};
}
onMounted(()=>{
invokeShowPosistion();
})
</script>
//
const showPosistion = function () {
postionFns[tempPosition.value] &&
(style.value = postionFns[tempPosition.value](
props.el,
popper.value,
innnerPosition
));
};
const invokeShowPosistion = function () {
if (innerVisible.value) {
popper.value.offsetWidth === 0
? setTimeout(showPosistion, 0)
: showPosistion();
//
setTimeout(() => innerVisible.value && showPosistion(), 2);
}
};
onMounted(() => {
invokeShowPosistion();
});
</script>

View File

@ -38,4 +38,4 @@ const styles = computed(() => {
</span>
</div>
</div>
</template>
</template>

View File

@ -25,23 +25,22 @@
</template>
<script setup name="LayRadio" lang="ts">
import { defineProps, defineEmits } from 'vue'
import { defineProps, defineEmits } from "vue";
const props =
defineProps<{
modelValue: string
disabled?: boolean
label?: string
name: string
}>()
const props = defineProps<{
modelValue: string;
disabled?: boolean;
label?: string;
name: string;
}>();
const emit = defineEmits(['update:modelValue','change'])
const emit = defineEmits(["update:modelValue", "change"]);
const handleClick = function () {
if (props.disabled) {
return
return;
}
emit('change', props.label)
emit('update:modelValue', props.label)
}
emit("change", props.label);
emit("update:modelValue", props.label);
};
</script>

View File

@ -1,29 +1,29 @@
.layui-rate,
.layui-rate * {
display: inline-block;
vertical-align: middle;
display: inline-block;
vertical-align: middle;
}
.layui-rate {
padding: 10px 5px 10px 0;
font-size: 0;
padding: 10px 5px 10px 0;
font-size: 0;
}
.layui-rate li i.layui-icon {
font-size: 20px;
color: #ffb800;
margin-right: 5px;
transition: all 0.3s;
-webkit-transition: all 0.3s;
font-size: 20px;
color: #ffb800;
margin-right: 5px;
transition: all 0.3s;
-webkit-transition: all 0.3s;
}
.layui-rate li i:hover {
cursor: pointer;
transform: scale(1.12);
-webkit-transform: scale(1.12);
cursor: pointer;
transform: scale(1.12);
-webkit-transform: scale(1.12);
}
.layui-rate[readonly] li i:hover {
cursor: default;
transform: scale(1);
}
cursor: default;
transform: scale(1);
}

View File

@ -1,4 +1,3 @@
<script lang="ts">
export default {
name: "LayRate",
@ -27,7 +26,11 @@ const props = withDefaults(defineProps<LayRateProps>(), {
half: false,
text: false,
isBlock: false,
icons: () => ['layui-icon-rate', 'layui-icon-rate-half', 'layui-icon-rate-solid']
icons: () => [
"layui-icon-rate",
"layui-icon-rate-half",
"layui-icon-rate-solid",
],
});
const emit = defineEmits(["update:modelValue", "select"]);
@ -36,7 +39,9 @@ const currentValue = ref<number>(props.modelValue);
//
const tempValue = ref(currentValue.value);
//
const isHalf = computed(()=>props.half && Math.round(currentValue.value) !== currentValue.value);
const isHalf = computed(
() => props.half && Math.round(currentValue.value) !== currentValue.value
);
//
const getValue = function (index: number, event: any): number {
@ -89,18 +94,25 @@ const action = function (index: number, event: any) {
:class="[
'layui-icon',
`${
icons[icons.length - (isHalf && index === Math.ceil(currentValue) ? 2: 1)]
icons[
icons.length -
(isHalf && index === Math.ceil(currentValue) ? 2 : 1)
]
}`,
]"
:style="{ color: theme }"
/>
<i v-else :class="['layui-icon'].concat(icons[0])" :style="{ color: theme }"/>
<i
v-else
:class="['layui-icon'].concat(icons[0])"
:style="{ color: theme }"
/>
</li>
</ul>
<template v-if="text">
<span class="layui-inline">
<slot :value="currentValue">
{{ currentValue + '星' }}
{{ currentValue + "星" }}
</slot>
</span>
</template>

View File

@ -1,25 +1,24 @@
.layui-row:after,
.layui-row:before {
content: '';
display: block;
clear: both;
content: "";
display: block;
clear: both;
}
/** generate space */
.generate-space(@a) {
.layui-col-space@{a} {
margin: -0.5px * @a;
}
.layui-col-space@{a} {
margin: -0.5px * @a;
}
.layui-col-space@{a}>* {
padding: 0.5px * @a;
}
.layui-col-space@{a} > * {
padding: 0.5px * @a;
}
}
.loop-generate-space(@index) when (@index <=30) {
.generate-space(@index);
.loop-generate-space(@index + 1);
.generate-space(@index);
.loop-generate-space(@index + 1);
}
.loop-generate-space(1);
@ -27,175 +26,169 @@
/** generate col xs */
.generate-col-xs(@a) {
.layui-col-xs@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-xs@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-xs-offset@{a} {
margin-left: 100% * (@a / 24);
}
.layui-col-xs-offset@{a} {
margin-left: 100% * (@a / 24);
}
}
.generate-col-sm(@a) {
.layui-col-sm@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-sm@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-sm-offset@{a} {
margin-left: 100% * (@a / 24);
}
.layui-col-sm-offset@{a} {
margin-left: 100% * (@a / 24);
}
}
.generate-col-md(@a) {
.layui-col-md@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-md@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-md-offset@{a} {
margin-left: 100% * (@a / 24);
}
.layui-col-md-offset@{a} {
margin-left: 100% * (@a / 24);
}
}
.generate-col-lg(@a) {
.layui-col-lg@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-lg@{a} {
float: left;
display: block;
position: relative;
box-sizing: border-box;
width: 100% * (@a / 24);
}
.layui-col-lg-offset@{a} {
margin-left: 100% * (@a / 24);
}
.layui-col-lg-offset@{a} {
margin-left: 100% * (@a / 24);
}
}
.loop-generate-col-xs(@index) when (@index <=24) {
.generate-col-xs(@index);
.loop-generate-col-xs(@index + 1)
.generate-col-xs(@index);
.loop-generate-col-xs(@index + 1);
}
.loop-generate-col-sm(@index) when (@index <=24) {
.generate-col-sm(@index);
.loop-generate-col-sm(@index + 1)
.generate-col-sm(@index);
.loop-generate-col-sm(@index + 1);
}
.loop-generate-col-md(@index) when (@index <=24) {
.generate-col-md(@index);
.loop-generate-col-md(@index + 1)
.generate-col-md(@index);
.loop-generate-col-md(@index + 1);
}
.loop-generate-col-lg(@index) when (@index <=24) {
.generate-col-lg(@index);
.loop-generate-col-lg(@index + 1)
.generate-col-lg(@index);
.loop-generate-col-lg(@index + 1);
}
@media screen and (max-width: 768px) {
.layui-hide-xs {
display: none !important;
}
.layui-hide-xs {
display: none !important;
}
.layui-show-xs-block {
display: block !important;
}
.layui-show-xs-block {
display: block !important;
}
.layui-show-xs-inline {
display: inline !important;
}
.layui-show-xs-inline {
display: inline !important;
}
.layui-show-xs-inline-block {
display: inline-block !important;
}
.layui-show-xs-inline-block {
display: inline-block !important;
}
.loop-generate-col-xs(1);
.loop-generate-col-xs(1);
}
@media screen and (min-width: 768px) {
.layui-container {
width: 750px;
}
.layui-container {
width: 750px;
}
.layui-hide-sm {
display: none !important;
}
.layui-hide-sm {
display: none !important;
}
.layui-show-sm-block {
display: block !important;
}
.layui-show-sm-block {
display: block !important;
}
.layui-show-sm-inline {
display: inline !important;
}
.layui-show-sm-inline {
display: inline !important;
}
.layui-show-sm-inline-block {
display: inline-block !important;
}
.layui-show-sm-inline-block {
display: inline-block !important;
}
.loop-generate-col-sm(1)
.loop-generate-col-sm(1);
}
@media screen and (min-width: 992px) {
.layui-container {
width: 970px;
}
.layui-container {
width: 970px;
}
.layui-hide-md {
display: none !important;
}
.layui-hide-md {
display: none !important;
}
.layui-show-md-block {
display: block !important;
}
.layui-show-md-block {
display: block !important;
}
.layui-show-md-inline {
display: inline !important;
}
.layui-show-md-inline {
display: inline !important;
}
.layui-show-md-inline-block {
display: inline-block !important;
}
.layui-show-md-inline-block {
display: inline-block !important;
}
.loop-generate-col-md(1)
.loop-generate-col-md(1);
}
@media screen and (min-width: 1200px) {
.layui-container {
width: 1170px;
}
.layui-container {
width: 1170px;
}
.layui-hide-lg {
display: none !important;
}
.layui-hide-lg {
display: none !important;
}
.layui-show-lg-block {
display: block !important;
}
.layui-show-lg-block {
display: block !important;
}
.layui-show-lg-inline {
display: inline !important;
}
.layui-show-lg-inline {
display: inline !important;
}
.layui-show-lg-inline-block {
display: inline-block !important;
}
.layui-show-lg-inline-block {
display: inline-block !important;
}
.loop-generate-col-lg(1)
}
.loop-generate-col-lg(1);
}

View File

@ -24,4 +24,3 @@ const classes = computed(() => {
<slot />
</div>
</template>

View File

@ -1,41 +1,41 @@
dl.layui-anim-upbit>dd input[type=checkbox] {
display: none;
dl.layui-anim-upbit > dd input[type="checkbox"] {
display: none;
}
dl.layui-anim-upbit>dd .layui-form-checkbox
,.layui-form-item dl.layui-anim-upbit>dd .layui-form-checkbox[lay-skin] {
margin-top: -3px;
dl.layui-anim-upbit > dd .layui-form-checkbox,
.layui-form-item dl.layui-anim-upbit > dd .layui-form-checkbox[lay-skin] {
margin-top: -3px;
}
// 多选样式
.layui-multiple-select-row {
position: absolute;
height: 100%;
top: 0;
left: 0;
right: 30px;
padding: 5px 0 5px 10px;
box-sizing: border-box;
overflow: hidden;
cursor: pointer;
.layui-multiple-select-badge{
width: ms-max-content;
width: max-content;
.layui-badge {
margin-left: 5px;
height: 28px;
line-height: 28px;
&:first-of-type{
margin-left: 0;
}
}
.layui-icon {
font-size: 12px;
padding-left: 3px;
&:hover{
cursor: pointer;
color: #FF5722;
}
}
position: absolute;
height: 100%;
top: 0;
left: 0;
right: 30px;
padding: 5px 0 5px 10px;
box-sizing: border-box;
overflow: hidden;
cursor: pointer;
.layui-multiple-select-badge {
width: ms-max-content;
width: max-content;
.layui-badge {
margin-left: 5px;
height: 28px;
line-height: 28px;
&:first-of-type {
margin-left: 0;
}
}
}
.layui-icon {
font-size: 12px;
padding-left: 3px;
&:hover {
cursor: pointer;
color: #ff5722;
}
}
}
}

View File

@ -2,32 +2,61 @@
<div
ref="selectRef"
class="layui-unselect layui-form-select"
:class="{'layui-form-selected' : openState}"
:class="{ 'layui-form-selected': openState }"
>
<div class="layui-select-title" @click="open">
<input
type="text"
:placeholder="selectItem.value !== null && Array.isArray(selectItem.value) && selectItem.value.length > 0 ? '' : (emptyMessage ?? placeholder)"
:placeholder="
selectItem.value !== null &&
Array.isArray(selectItem.value) &&
selectItem.value.length > 0
? ''
: emptyMessage ?? placeholder
"
:disabled="disabled"
readonly
:value="!selectItem.multiple && selectItem.value !== null ? selectItem.label : null"
:value="
!selectItem.multiple && selectItem.value !== null
? selectItem.label
: null
"
:name="name"
:class="['layui-input', 'layui-unselect', {'layui-disabled': disabled}]"
:class="[
'layui-input',
'layui-unselect',
{ 'layui-disabled': disabled },
]"
/>
<i :class="['layui-edge', {'layui-disabled': disabled}]" />
<i :class="['layui-edge', { 'layui-disabled': disabled }]" />
<!-- 多选 -->
<div v-if="selectItem.multiple && Array.isArray(selectItem.label)" class="layui-multiple-select-row">
<div
v-if="selectItem.multiple && Array.isArray(selectItem.label)"
class="layui-multiple-select-row"
>
<div class="layui-multiple-select-badge">
<template v-for="(item, index) in selectItem.label" :key="index">
<lay-badge theme="green">
<span>{{item}}</span>
<i :class="['layui-icon', {'layui-icon-close': true}]"
v-if="!disabled
&& !(Array.isArray(selectItem.value) && selectItem.value.length > 0 && disabledItemMap[selectItem.value[index]])"
@click="removeItemHandle($event, {
label: item,
value: Array.isArray(selectItem.value)? selectItem.value[index] : null
})">
<span>{{ item }}</span>
<i
:class="['layui-icon', { 'layui-icon-close': true }]"
v-if="
!disabled &&
!(
Array.isArray(selectItem.value) &&
selectItem.value.length > 0 &&
disabledItemMap[selectItem.value[index]]
)
"
@click="
removeItemHandle($event, {
label: item,
value: Array.isArray(selectItem.value)
? selectItem.value[index]
: null,
})
"
>
</i>
</lay-badge>
</template>
@ -37,7 +66,10 @@
<dl class="layui-anim layui-anim-upbit">
<!-- 多选不支持空提示 -->
<template v-if="!multiple && showEmpty">
<lay-select-option :value="null" :label="emptyMessage??placeholder"></lay-select-option>
<lay-select-option
:value="null"
:label="emptyMessage ?? placeholder"
></lay-select-option>
</template>
<slot />
</dl>
@ -45,38 +77,51 @@
</template>
<script setup name="LaySelect" lang="ts">
import './index.less';
import LaySelectOption from '../selectOption/index.vue'
import { defineProps, provide, isProxy, ref, watch, computed, reactive, toRefs, Ref } from 'vue'
import { useClickOutside } from '@layui/hooks-vue'
import { SelectItem} from '../type'
import "./index.less";
import LaySelectOption from "../selectOption/index.vue";
import {
defineProps,
provide,
isProxy,
ref,
watch,
computed,
reactive,
toRefs,
Ref,
} from "vue";
import { useClickOutside } from "@layui/hooks-vue";
import { SelectItem } from "../type";
const selectRef = ref<null | HTMLElement>(null)
const isClickOutside = useClickOutside(selectRef)
const selectRef = ref<null | HTMLElement>(null);
const isClickOutside = useClickOutside(selectRef);
watch(isClickOutside, () => {
if (isClickOutside.value) {
openState.value = false
openState.value = false;
}
})
});
const props = withDefaults(defineProps<{
modelValue?: string | number | [] | null
name?: string
placeholder?: string
disabled?: boolean
showEmpty?: boolean
emptyMessage?: string
multiple?: boolean
}>(), {
modelValue : null,
placeholder : '请选择',
disabled : false,
showEmpty : true,
multiple : false
})
const props = withDefaults(
defineProps<{
modelValue?: string | number | [] | null;
name?: string;
placeholder?: string;
disabled?: boolean;
showEmpty?: boolean;
emptyMessage?: string;
multiple?: boolean;
}>(),
{
modelValue: null,
placeholder: "请选择",
disabled: false,
showEmpty: true,
multiple: false,
}
);
const openState = ref(false)
const openState = ref(false);
const open = function () {
//
@ -84,42 +129,58 @@ const open = function () {
openState.value = false;
return;
}
openState.value = !openState.value
}
openState.value = !openState.value;
};
const emit = defineEmits(['update:modelValue', 'change'])
const emit = defineEmits(["update:modelValue", "change"]);
const selectItem = ref<SelectItem>({
value : !props.multiple ? props.modelValue : (props.modelValue ? ([] as any[]).concat(props.modelValue) : []),
label : props.multiple ? [] : null,
multiple : props.multiple
value: !props.multiple
? props.modelValue
: props.modelValue
? ([] as any[]).concat(props.modelValue)
: [],
label: props.multiple ? [] : null,
multiple: props.multiple,
} as SelectItem);
watch(()=>selectItem.value.value, (val) =>{
emit('update:modelValue', val)
emit('change', val)
}, {
deep : true
})
watch(()=>props.modelValue, (value) => {
selectItem.value.value = value;
if (!value && value !== 0) {
props.multiple && (selectItem.value.value = []);
selectItem.value.label = props.multiple ? [] : null;
watch(
() => selectItem.value.value,
(val) => {
emit("update:modelValue", val);
emit("change", val);
},
{
deep: true,
}
})
);
watch(
() => props.modelValue,
(value) => {
selectItem.value.value = value;
if (!value && value !== 0) {
props.multiple && (selectItem.value.value = []);
selectItem.value.label = props.multiple ? [] : null;
}
}
);
//
const disabledItemMap : {[key: string|number]:boolean} = {};
const selectItemHandle = function(_selectItem : SelectItem, isChecked ?: boolean) {
const disabledItemMap: { [key: string | number]: boolean } = {};
const selectItemHandle = function (
_selectItem: SelectItem,
isChecked?: boolean
) {
if (!props.multiple) {
openState.value = false;
}
disabledItemMap[(_selectItem.value as string | number)] = _selectItem.disabled as boolean;
if (typeof isChecked !== 'boolean') {
props.multiple ? (selectItem.value.label as any[]).push(_selectItem.label) : selectItem.value.label = _selectItem.label;
return ;
disabledItemMap[_selectItem.value as string | number] =
_selectItem.disabled as boolean;
if (typeof isChecked !== "boolean") {
props.multiple
? (selectItem.value.label as any[]).push(_selectItem.label)
: (selectItem.value.label = _selectItem.label);
return;
}
let values = selectItem.value.value;
if (props.multiple && Array.isArray(values)) {
@ -138,14 +199,13 @@ const selectItemHandle = function(_selectItem : SelectItem, isChecked ?: boolean
selectItem.value.value = _selectItem.value;
selectItem.value.label = _selectItem.label;
}
}
};
const removeItemHandle = function(e : MouseEvent, _selectItem : SelectItem) {
const removeItemHandle = function (e: MouseEvent, _selectItem: SelectItem) {
e.stopPropagation();
selectItemHandle(_selectItem, false);
}
provide('selectItemHandle', selectItemHandle)
provide('selectItem', selectItem)
};
provide("selectItemHandle", selectItemHandle);
provide("selectItem", selectItem);
</script>

View File

@ -1,14 +1,16 @@
<template>
<dd
:value="value"
:class="[
{'layui-this' : selected},
{'layui-disabled' : disabled}
]"
:class="[{ 'layui-this': selected }, { 'layui-disabled': disabled }]"
@click="selectHandle"
>
<template v-if="selectItem.multiple">
<lay-checkbox skin="primary" v-model="selected" @change="selectHandle" label=""></lay-checkbox>
<lay-checkbox
skin="primary"
v-model="selected"
@change="selectHandle"
label=""
></lay-checkbox>
</template>
<slot>{{ label }}</slot>
</dd>
@ -16,45 +18,48 @@
<script lang="ts">
export default {
name : 'LaySelectOption'
}
name: "LaySelectOption",
};
</script>
<script setup lang="ts">
import LayCheckbox from '../checkbox';
import { SelectItem, SelectItemHandle } from '../type'
import { computed, defineProps, inject, onMounted, Ref} from 'vue'
import LayCheckbox from "../checkbox";
import { SelectItem, SelectItemHandle } from "../type";
import { computed, defineProps, inject, onMounted, Ref } from "vue";
const props = withDefaults(
defineProps<{
value: string | null | undefined
label?: string
disabled?: boolean
value: string | null | undefined;
label?: string;
disabled?: boolean;
}>(),
{
disabled: false,
}
)
);
const selectItemHandle = inject('selectItemHandle') as SelectItemHandle
const selectItem = inject('selectItem') as Ref<SelectItem>
const selectItemHandle = inject("selectItemHandle") as SelectItemHandle;
const selectItem = inject("selectItem") as Ref<SelectItem>;
const selectHandle = function () {
!props.disabled && callSelectItemHandle(!selected.value);
}
const callSelectItemHandle = function(isChecked ?: boolean){
selectItemHandle({
value : props.value,
label : props.label,
disabled : props.disabled
}, isChecked);
}
const selected = computed(()=>{
};
const callSelectItemHandle = function (isChecked?: boolean) {
selectItemHandle(
{
value: props.value,
label: props.label,
disabled: props.disabled,
},
isChecked
);
};
const selected = computed(() => {
const selectValues = selectItem.value.value;
if (Array.isArray(selectValues)) {
return (selectValues as any[]).indexOf(props.value) > -1;
}
return selectItem.value.value === props.value
})
onMounted(() => selected.value && callSelectItemHandle())
return selectItem.value.value === props.value;
});
onMounted(() => selected.value && callSelectItemHandle());
</script>

View File

@ -1,5 +1,5 @@
.layui-side {
overflow: auto;
box-sizing: border-box;
min-height: 300px;
}
overflow: auto;
box-sizing: border-box;
min-height: 300px;
}

View File

@ -27,4 +27,4 @@ const styles = computed<CSSProperties>(() => {
<div class="layui-side" :style="styles">
<slot />
</div>
</template>
</template>

View File

@ -54,4 +54,4 @@ const handleClick = function () {
<i />
</div>
</span>
</template>
</template>

View File

@ -1,5 +1,9 @@
<template>
<div class="layui-tab" :class="[type ? 'layui-tab-' + type : '']" v-if="active">
<div
class="layui-tab"
:class="[type ? 'layui-tab-' + type : '']"
v-if="active"
>
<ul class="layui-tab-title">
<li
v-for="(children, index) in childrens"
@ -23,12 +27,12 @@
<script lang="ts">
export default {
name: 'LayTab',
}
name: "LayTab",
};
</script>
<script setup lang="ts">
import tabItem from '../tabItem/index.vue'
import tabItem from "../tabItem/index.vue";
import {
defineProps,
Component,
@ -39,73 +43,74 @@ import {
Ref,
ref,
watch,
} from 'vue'
} from "vue";
const slot = useSlots()
const slots = slot.default && slot.default()
const childrens: Ref<VNode[]> = ref([])
const slot = useSlots();
const slots = slot.default && slot.default();
const childrens: Ref<VNode[]> = ref([]);
const setItemInstanceBySlot = function (nodeList: VNode[]) {
nodeList?.map((item) => {
let component = item.type as Component
let component = item.type as Component;
if (component.name != tabItem.name) {
setItemInstanceBySlot(item.children as VNode[])
setItemInstanceBySlot(item.children as VNode[]);
} else {
childrens.value.push(item)
childrens.value.push(item);
}
})
}
});
};
const props = defineProps<{
type?: string
modelValue: string
allowClose?: boolean
beforeClose?: Function
beforeLeave?: Function
}>()
type?: string;
modelValue: string;
allowClose?: boolean;
beforeClose?: Function;
beforeLeave?: Function;
}>();
const emit = defineEmits(['update:modelValue', 'change', 'close'])
const emit = defineEmits(["update:modelValue", "change", "close"]);
const active = computed({
get() {
return props.modelValue
return props.modelValue;
},
set(val) {
emit('update:modelValue', val)
emit("update:modelValue", val);
},
})
const slotsChange = ref(true)
});
const slotsChange = ref(true);
const change = function (id: any) {
// return false, tab
if (props.beforeLeave && props.beforeLeave(id) === false) {
return ;
return;
}
emit('update:modelValue', id)
emit('change', id)
}
emit("update:modelValue", id);
emit("change", id);
};
const close = function (index : number, id: any) {
const close = function (index: number, id: any) {
// return false, tab
if (props.beforeClose && props.beforeClose(id) === false) {
return ;
return;
}
// tab
childrens.value.splice(index, 1);
// tabtab
if (active.value === id) {
const nextChildren = childrens.value[(index === childrens.value.length ? 0 : index)];
change(nextChildren && nextChildren.props ? nextChildren.props.id : "")
const nextChildren =
childrens.value[index === childrens.value.length ? 0 : index];
change(nextChildren && nextChildren.props ? nextChildren.props.id : "");
}
emit('close', id)
}
emit("close", id);
};
watch(slotsChange, function () {
childrens.value = []
setItemInstanceBySlot((slot.default && slot.default()) as VNode[])
})
childrens.value = [];
setItemInstanceBySlot((slot.default && slot.default()) as VNode[]);
});
provide('active', active)
provide('slotsChange', slotsChange)
provide("active", active);
provide("slotsChange", slotsChange);
</script>

View File

@ -6,24 +6,25 @@
<script lang="ts">
export default {
name: 'LayTabItem',
}
name: "LayTabItem",
};
</script>
<script setup name="LayTabItem" lang="ts">
import { withDefaults, defineProps, inject, Ref } from 'vue'
import { withDefaults, defineProps, inject, Ref } from "vue";
const props = withDefaults(
defineProps<{
id: string
title: string
closable?: boolean
}>(),{
closable: true
id: string;
title: string;
closable?: boolean;
}>(),
{
closable: true,
}
);
const active = inject('active')
const slotsChange: Ref<boolean> = inject('slotsChange') as Ref<boolean>
slotsChange.value = !slotsChange.value
const active = inject("active");
const slotsChange: Ref<boolean> = inject("slotsChange") as Ref<boolean>;
slotsChange.value = !slotsChange.value;
</script>

View File

@ -51,9 +51,11 @@ const slots = slot.default && slot.default();
const allChecked = ref(false);
const tableSelectedKeys = ref([...props.selectedKeys]);
const tableColumns = ref([...props.columns]);
const tableColumnKeys = ref(props.columns.map((item: any) => {
return item.key;
}));
const tableColumnKeys = ref(
props.columns.map((item: any) => {
return item.key;
})
);
const changeAll = function (checked: any) {
const ids = props.dataSource.map((item: any) => {

View File

@ -45,4 +45,4 @@ const onBlur = function () {
@focus="onFocus"
@blur="onBlur"
/>
</template>
</template>

View File

@ -1,59 +1,59 @@
.layui-timeline {
padding-left: 5px;
padding-left: 5px;
}
.layui-timeline-item {
position: relative;
padding-bottom: 20px;
position: relative;
padding-bottom: 20px;
}
.layui-timeline-axis {
position: absolute;
left: -5px;
top: 0;
z-index: 10;
width: 20px;
height: 20px;
line-height: 20px;
background-color: #fff;
color: #5fb878;
border-radius: 50%;
text-align: center;
cursor: pointer;
position: absolute;
left: -5px;
top: 0;
z-index: 10;
width: 20px;
height: 20px;
line-height: 20px;
background-color: #fff;
color: #5fb878;
border-radius: 50%;
text-align: center;
cursor: pointer;
}
.layui-timeline-axis:hover {
color: #ff5722;
color: #ff5722;
}
.layui-timeline-item:before {
content: '';
position: absolute;
left: 5px;
top: 0;
z-index: 0;
width: 1px;
height: 100%;
content: "";
position: absolute;
left: 5px;
top: 0;
z-index: 0;
width: 1px;
height: 100%;
}
.layui-timeline-item:first-child:before {
display: block;
display: block;
}
.layui-timeline-item:last-child:before {
display: none;
display: none;
}
.layui-timeline-content {
padding-left: 25px;
padding-left: 25px;
}
.layui-timeline-title {
position: relative;
margin-bottom: 10px;
line-height: 22px;
position: relative;
margin-bottom: 10px;
line-height: 22px;
}
.layui-timeline-item:before {
background-color: #eee;
}
background-color: #eee;
}

View File

@ -5,11 +5,11 @@ export default {
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>
<ul class="layui-timeline">
<slot />
</ul>
</template>
</template>

View File

@ -1,6 +1,6 @@
<script lang="ts">
import usePopper from "../popper/usePopper";
import { defineComponent} from "vue";
import { defineComponent } from "vue";
export default defineComponent({
name: "LayTooltip",
props: {
@ -22,12 +22,12 @@ export default defineComponent({
},
visible: {
type: Boolean,
default: true
default: true,
},
isCanHide: {
type: Boolean,
default: true
}
default: true,
},
},
render() {
return this.$slots.default && this.$slots.default()[0];
@ -35,8 +35,8 @@ export default defineComponent({
mounted() {
const _this = this;
this.$nextTick(() => {
usePopper.createPopper(_this.$el, _this.$props, 'hover')
usePopper.createPopper(_this.$el, _this.$props, "hover");
});
}
},
});
</script>

View File

@ -1,3 +1,3 @@
.layui-transfer .layui-btn + .layui-btn {
margin-left: 0;
}
margin-left: 0;
}

View File

@ -182,4 +182,4 @@ const remove = function () {
</div>
</div>
</div>
</template>
</template>

View File

@ -1,48 +1,48 @@
<script lang="ts">
export default {
name: 'TreeNode',
}
name: "TreeNode",
};
</script>
<script setup lang="ts">
import { StringOrNumber } from './tree.type'
import { Nullable } from '../type'
import { StringOrNumber } from "./tree.type";
import { Nullable } from "../type";
import LayIcon from '../icon'
import LayCheckbox from '../checkbox'
import { Ref } from 'vue'
import { Tree } from './tree'
import LayIcon from "../icon";
import LayCheckbox from "../checkbox";
import { Ref } from "vue";
import { Tree } from "./tree";
type CustomKey = string | number
type CustomString = (() => string) | string
type CustomKey = string | number;
type CustomString = (() => string) | string;
interface TreeData {
id: CustomKey
title: CustomString
children: TreeData[]
parentKey: Nullable<StringOrNumber>
isRoot: boolean
isChecked: Ref<boolean>
isDisabled: Ref<boolean>
isLeaf: Ref<boolean>
hasNextSibling: boolean
parentNode: Nullable<TreeData>
id: CustomKey;
title: CustomString;
children: TreeData[];
parentKey: Nullable<StringOrNumber>;
isRoot: boolean;
isChecked: Ref<boolean>;
isDisabled: Ref<boolean>;
isLeaf: Ref<boolean>;
hasNextSibling: boolean;
parentNode: Nullable<TreeData>;
}
interface TreeNodeProps {
tree: Tree
nodeList: TreeData[]
showCheckbox: boolean
showLine: boolean
onlyIconControl: boolean
tree: Tree;
nodeList: TreeData[];
showCheckbox: boolean;
showLine: boolean;
onlyIconControl: boolean;
}
interface TreeNodeEmits {
(e: 'node-click', node: TreeData): void
(e: "node-click", node: TreeData): void;
}
const props = defineProps<TreeNodeProps>()
const emit = defineEmits<TreeNodeEmits>()
const props = defineProps<TreeNodeProps>();
const emit = defineEmits<TreeNodeEmits>();
function renderLineShort(node: TreeData) {
return (
@ -52,7 +52,7 @@ function renderLineShort(node: TreeData) {
(!node.parentNode.hasNextSibling ||
//线
(node.parentNode.hasNextSibling && !node.parentNode.children))
)
);
}
/**
* 展开收起 icon样式
@ -61,33 +61,35 @@ function renderLineShort(node: TreeData) {
const nodeIconType = (node: TreeData): string => {
if (!props.showLine) {
if (node.children.length > 0) {
return 'layui-tree-iconArrow '
return "layui-tree-iconArrow ";
}
return ''
return "";
}
if (node.children.length !== 0) {
return !node.isLeaf.value ? 'layui-icon-addition' : 'layui-icon-subtraction'
return !node.isLeaf.value
? "layui-icon-addition"
: "layui-icon-subtraction";
}
return 'layui-icon-file'
}
return "layui-icon-file";
};
function recursiveNodeClick(node: TreeData) {
emit('node-click', node)
emit("node-click", node);
}
function handleChange(checked: boolean, node: TreeData) {
props.tree.setCheckedKeys(checked, node)
props.tree.setCheckedKeys(checked, node);
}
function handleIconClick(node: TreeData) {
node.isLeaf.value = !node.isLeaf.value
node.isLeaf.value = !node.isLeaf.value;
}
function handleTitleClick(node: TreeData) {
if (!props.onlyIconControl) {
handleIconClick(node)
handleIconClick(node);
}
emit('node-click', node)
emit("node-click", node);
}
</script>
@ -119,7 +121,7 @@ function handleTitleClick(node: TreeData) {
label=""
@change="
(checked) => {
handleChange(checked, node)
handleChange(checked, node);
}
"
>

View File

@ -6,50 +6,50 @@
-->
<script lang="ts">
export default {
name: 'LayTree',
}
name: "LayTree",
};
// import { TreeEmits, TreeProps as Tp } from './tree.type'
</script>
<script lang="ts" setup>
import TreeNode from './TreeNode.vue'
import { computed } from 'vue'
import { useTree } from './useTree'
import { TreeData } from './tree'
import TreeNode from "./TreeNode.vue";
import { computed } from "vue";
import { useTree } from "./useTree";
import { TreeData } from "./tree";
type StringFn = () => string
type StringOrNumber = string | number
type KeysType = (number | string)[]
type EditType = boolean | ('add' | 'update' | 'delete')
type StringFn = () => string;
type StringOrNumber = string | number;
type KeysType = (number | string)[];
type EditType = boolean | ("add" | "update" | "delete");
interface OriginalTreeData {
title: StringFn | string
id: StringOrNumber
field: StringFn | string
children?: OriginalTreeData[]
disabled?: boolean
title: StringFn | string;
id: StringOrNumber;
field: StringFn | string;
children?: OriginalTreeData[];
disabled?: boolean;
}
interface TreeProps {
checkedKeys?: KeysType
data: OriginalTreeData
showCheckbox?: boolean
edit?: EditType
accordion?: boolean
onlyIconControl?: boolean
showLine?: boolean
disabled?: boolean
checkedKeys?: KeysType;
data: OriginalTreeData;
showCheckbox?: boolean;
edit?: EditType;
accordion?: boolean;
onlyIconControl?: boolean;
showLine?: boolean;
disabled?: boolean;
replaceFields?: {
id?: string
children?: string
title?: string
}
id?: string;
children?: string;
title?: string;
};
}
interface TreeEmits {
(e: 'update:checkedKeys', keys: KeysType): void
(e: 'update:expandKeys', keys: KeysType): void
(e: 'node-click', node: OriginalTreeData): void
(e: "update:checkedKeys", keys: KeysType): void;
(e: "update:expandKeys", keys: KeysType): void;
(e: "node-click", node: OriginalTreeData): void;
}
const props = withDefaults(defineProps<TreeProps>(), {
@ -61,28 +61,28 @@ const props = withDefaults(defineProps<TreeProps>(), {
showLine: true,
replaceFields: () => {
return {
id: 'id',
children: 'children',
title: 'title',
}
id: "id",
children: "children",
title: "title",
};
},
})
});
const emit = defineEmits<TreeEmits>()
const emit = defineEmits<TreeEmits>();
const className = computed(() => {
return {
'layui-tree': true,
'layui-form': props.showCheckbox,
'layui-tree-line': props.showLine,
}
})
"layui-tree": true,
"layui-form": props.showCheckbox,
"layui-tree-line": props.showLine,
};
});
const { tree, nodeList } = useTree(props, emit)
const { tree, nodeList } = useTree(props, emit);
function handleClick(node: TreeData) {
const originNode = tree.getOriginData(node.id)
emit('node-click', originNode)
const originNode = tree.getOriginData(node.id);
emit("node-click", originNode);
}
</script>
<template>

View File

@ -4,16 +4,20 @@
* @param elem dom
* */
export function getTop(elem) {
return elem.offsetTop + (elem.offsetParent && getTop(elem.offsetParent) || 0);
return (
elem.offsetTop + ((elem.offsetParent && getTop(elem.offsetParent)) || 0)
);
}
/**
* 获取 left 属性值
* <p>
* @param elem dom
* */
* */
export function getLeft(elem) {
return elem.offsetLeft + (elem.offsetParent && getLeft(elem.offsetParent) || 0);
return (
elem.offsetLeft + ((elem.offsetParent && getLeft(elem.offsetParent)) || 0)
);
}
/**
@ -22,9 +26,11 @@ export function getLeft(elem) {
* @param elem dom
* @param events 事件
* @param handler 事件回调
* */
* */
export function on(elem, events, handler) {
[].concat(events).forEach(event => elem.addEventListener(event, handler, false));
[]
.concat(events)
.forEach((event) => elem.addEventListener(event, handler, false));
}
/**
@ -33,13 +39,13 @@ export function on(elem, events, handler) {
* @param elem dom
* @param events 事件
* @param handler 事件回调
* */
export function once (elem, events, handler) {
const listener = function (_this, args) {
handler.apply(_this, args)
off(elem, events, listener);
}
on(elem, events, listener)
* */
export function once(elem, events, handler) {
const listener = function (_this, args) {
handler.apply(_this, args);
off(elem, events, listener);
};
on(elem, events, listener);
}
/**
@ -48,7 +54,9 @@ export function once (elem, events, handler) {
* @param elem dom
* @param events 事件
* @param handler 事件回调
* */
* */
export function off(elem, events, handler) {
[].concat(events).forEach(event => elem.removeEventListener(event, handler, false));
}
[]
.concat(events)
.forEach((event) => elem.removeEventListener(event, handler, false));
}