集成 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", "dev": "vite",
"build": "vite build --emptyOutDir && npm run build:types", "build": "vite build --emptyOutDir && npm run build:types",
"build:types": "rimraf types && tsc -d", "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": { "peerDependencies": {
"vue": "^3.2.26", "vue": "^3.2.26",
@ -53,6 +54,7 @@
"escape-html": "^1.0.3", "escape-html": "^1.0.3",
"less": "^4.1.2", "less": "^4.1.2",
"markdown-it-container": "^3.0.0", "markdown-it-container": "^3.0.0",
"prettier": "^2.5.1",
"prismjs": "^1.25.0", "prismjs": "^1.25.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"rollup": "^2.61.0", "rollup": "^2.61.0",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,13 +11,13 @@
</template> </template>
<script setup name="LayBreadcrumbItem" lang="ts"> <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<{ const props = defineProps<{
title?: string title?: string;
}>() }>();
const separator = inject('separator') const separator = inject("separator");
</script> </script>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,50 +1,60 @@
<template> <template>
<div class="layui-colla-item"> <div class="layui-colla-item">
<h2 :class="['layui-colla-title', {'layui-disabled' : disabled}]" @click="showHandle"> <h2
<slot name="title" :props="props">{{ title}}</slot> :class="['layui-colla-title', { 'layui-disabled': disabled }]"
<i class="layui-icon layui-colla-icon">{{ isShow ? '' : '' }}</i> @click="showHandle"
>
<slot name="title" :props="props">{{ title }}</slot>
<i class="layui-icon layui-colla-icon">{{ isShow ? "" : "" }}</i>
</h2> </h2>
<div class="layui-colla-content" :class="isShow ? 'layui-show' : ''"> <div class="layui-colla-content" :class="isShow ? 'layui-show' : ''">
<p> <p>
<slot :props="props"/> <slot :props="props" />
</p> </p>
</div> </div>
</div> </div>
</template> </template>
<script setup name="LayCollapseItem" lang="ts"> <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( const props = withDefaults(
defineProps<{ defineProps<{
id: number | string id: number | string;
title: string title: string;
disabled?: boolean 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 () { const showHandle = function () {
if (props.disabled) { if (props.disabled) {
return ; return;
} }
const _isShow = isShow.value; const _isShow = isShow.value;
// //
if (accordion) { if (accordion) {
activeValues.value = !_isShow ? [props.id] : []; activeValues.value = !_isShow ? [props.id] : [];
} else if (_isShow) { // --> } else if (_isShow) {
activeValues.value.splice(activeValues.value.indexOf(props.id), 1) // -->
} else { // --> activeValues.value.splice(activeValues.value.indexOf(props.id), 1);
activeValues.value.push(props.id) } 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); emit("change", props.id, !_isShow, activeValues.value);
} };
</script> </script>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,11 +7,11 @@
</template> </template>
<script setup name="LayDropdownItem" lang="ts"> <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 () { const click = function () {
openState.value = false openState.value = false;
} };
</script> </script>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,3 @@
<script lang="ts"> <script lang="ts">
export default { export default {
name: "LayRate", name: "LayRate",
@ -27,7 +26,11 @@ const props = withDefaults(defineProps<LayRateProps>(), {
half: false, half: false,
text: false, text: false,
isBlock: 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"]); const emit = defineEmits(["update:modelValue", "select"]);
@ -36,7 +39,9 @@ const currentValue = ref<number>(props.modelValue);
// //
const tempValue = ref(currentValue.value); 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 { const getValue = function (index: number, event: any): number {
@ -89,18 +94,25 @@ const action = function (index: number, event: any) {
:class="[ :class="[
'layui-icon', '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 }" :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> </li>
</ul> </ul>
<template v-if="text"> <template v-if="text">
<span class="layui-inline"> <span class="layui-inline">
<slot :value="currentValue"> <slot :value="currentValue">
{{ currentValue + '星' }} {{ currentValue + "星" }}
</slot> </slot>
</span> </span>
</template> </template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,16 +4,20 @@
* @param elem dom * @param elem dom
* */ * */
export function getTop(elem) { export function getTop(elem) {
return elem.offsetTop + (elem.offsetParent && getTop(elem.offsetParent) || 0); return (
elem.offsetTop + ((elem.offsetParent && getTop(elem.offsetParent)) || 0)
);
} }
/** /**
* 获取 left 属性值 * 获取 left 属性值
* <p> * <p>
* @param elem dom * @param elem dom
* */ * */
export function getLeft(elem) { 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 elem dom
* @param events 事件 * @param events 事件
* @param handler 事件回调 * @param handler 事件回调
* */ * */
export function on(elem, events, 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 elem dom
* @param events 事件 * @param events 事件
* @param handler 事件回调 * @param handler 事件回调
* */ * */
export function once (elem, events, handler) { export function once(elem, events, handler) {
const listener = function (_this, args) { const listener = function (_this, args) {
handler.apply(_this, args) handler.apply(_this, args);
off(elem, events, listener); off(elem, events, listener);
} };
on(elem, events, listener) on(elem, events, listener);
} }
/** /**
@ -48,7 +54,9 @@ export function once (elem, events, handler) {
* @param elem dom * @param elem dom
* @param events 事件 * @param events 事件
* @param handler 事件回调 * @param handler 事件回调
* */ * */
export function off(elem, events, 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));
}