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

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

3
.prettierrc Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ export default {
<script setup lang="ts">
import { defineProps } from "vue";
import "./index.less"
import "./index.less";
const props = defineProps<{
nm?: boolean;

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ export default {
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,8 +7,8 @@
}
.layui-form .layui-form-item {
.layui-input-block
,.layui-input-inline{
.layui-input-block,
.layui-input-inline {
.layui-form-danger {
border-color: #ff5722 !important;
}
@ -33,7 +33,6 @@
animation: layui-top-show-anim 0.3s ease 1;
}
@keyframes layui-top-show-anim {
0% {
opacity: 0.3;

View File

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

View File

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

View File

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

View File

@ -27,7 +27,7 @@
height: @size;
line-height: @size;
}
&[position=right]{
&[position="right"] {
.layui-input {
padding: 0 @size 0 0;
}
@ -91,7 +91,7 @@
-moz-appearance: textfield;
}
&[position=right]{
&[position="right"] {
.layui-subtraction-btn {
right: 0;
border-right-width: 0px;
@ -102,16 +102,15 @@
}
}
&[size=md] {
.set-size(@md-wdith,@md, @md-right)
&[size="md"] {
.set-size(@md-wdith,@md, @md-right);
}
&[size=sm] {
.set-size(@sm-wdith, @sm, @sm-right)
&[size="sm"] {
.set-size(@sm-wdith, @sm, @sm-right);
}
&[size=xs] {
.set-size(@xs-wdith, @xs, @xs-right)
&[size="xs"] {
.set-size(@xs-wdith, @xs, @xs-right);
}
}

View File

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

View File

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

View File

@ -8,19 +8,18 @@
</template>
<script setup name="LayMenuChildItem" lang="ts">
import { defineProps, inject, Ref, useSlots } from 'vue'
import { defineProps, inject, Ref, useSlots } from "vue";
const slots = useSlots()
const slots = useSlots();
const props =
defineProps<{
id: string
title: string
}>()
const props = defineProps<{
id: string;
title: string;
}>();
const selectedKey: Ref<string> = inject('selectedKey') as Ref<string>
const selectedKey: Ref<string> = inject("selectedKey") as Ref<string>;
const selectHandle = function () {
selectedKey.value = props.id
}
selectedKey.value = props.id;
};
</script>

View File

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

View File

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

View File

@ -1,11 +1,11 @@
<script lang="ts">
export default {
name: "LayPanel"
}
name: "LayPanel",
};
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>

View File

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

View File

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

View File

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

View File

@ -1,13 +1,12 @@
.layui-row:after,
.layui-row:before {
content: '';
content: "";
display: block;
clear: both;
}
/** generate space */
.generate-space(@a) {
.layui-col-space@{a} {
margin: -0.5px * @a;
}
@ -27,7 +26,6 @@
/** generate col xs */
.generate-col-xs(@a) {
.layui-col-xs@{a} {
float: left;
display: block;
@ -42,7 +40,6 @@
}
.generate-col-sm(@a) {
.layui-col-sm@{a} {
float: left;
display: block;
@ -57,7 +54,6 @@
}
.generate-col-md(@a) {
.layui-col-md@{a} {
float: left;
display: block;
@ -72,7 +68,6 @@
}
.generate-col-lg(@a) {
.layui-col-lg@{a} {
float: left;
display: block;
@ -88,22 +83,22 @@
.loop-generate-col-xs(@index) when (@index <=24) {
.generate-col-xs(@index);
.loop-generate-col-xs(@index + 1)
.loop-generate-col-xs(@index + 1);
}
.loop-generate-col-sm(@index) when (@index <=24) {
.generate-col-sm(@index);
.loop-generate-col-sm(@index + 1)
.loop-generate-col-sm(@index + 1);
}
.loop-generate-col-md(@index) when (@index <=24) {
.generate-col-md(@index);
.loop-generate-col-md(@index + 1)
.loop-generate-col-md(@index + 1);
}
.loop-generate-col-lg(@index) when (@index <=24) {
.generate-col-lg(@index);
.loop-generate-col-lg(@index + 1)
.loop-generate-col-lg(@index + 1);
}
@media screen and (max-width: 768px) {
@ -126,7 +121,6 @@
.loop-generate-col-xs(1);
}
@media screen and (min-width: 768px) {
.layui-container {
width: 750px;
@ -148,10 +142,9 @@
display: inline-block !important;
}
.loop-generate-col-sm(1)
.loop-generate-col-sm(1);
}
@media screen and (min-width: 992px) {
.layui-container {
width: 970px;
@ -173,7 +166,7 @@
display: inline-block !important;
}
.loop-generate-col-md(1)
.loop-generate-col-md(1);
}
@media screen and (min-width: 1200px) {
@ -197,5 +190,5 @@
display: inline-block !important;
}
.loop-generate-col-lg(1)
.loop-generate-col-lg(1);
}

View File

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

View File

@ -1,9 +1,9 @@
dl.layui-anim-upbit>dd input[type=checkbox] {
dl.layui-anim-upbit > dd input[type="checkbox"] {
display: none;
}
dl.layui-anim-upbit>dd .layui-form-checkbox
,.layui-form-item dl.layui-anim-upbit>dd .layui-form-checkbox[lay-skin] {
dl.layui-anim-upbit > dd .layui-form-checkbox,
.layui-form-item dl.layui-anim-upbit > dd .layui-form-checkbox[lay-skin] {
margin-top: -3px;
}
@ -34,7 +34,7 @@ dl.layui-anim-upbit>dd .layui-form-checkbox
padding-left: 3px;
&:hover {
cursor: pointer;
color: #FF5722;
color: #ff5722;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,7 +27,7 @@
}
.layui-timeline-item:before {
content: '';
content: "";
position: absolute;
left: 5px;
top: 0;

View File

@ -5,7 +5,7 @@ export default {
</script>
<script setup lang="ts">
import "./index.less"
import "./index.less";
</script>
<template>

View File

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

View File

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

View File

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

View File

@ -4,7 +4,9 @@
* @param elem dom
* */
export function getTop(elem) {
return elem.offsetTop + (elem.offsetParent && getTop(elem.offsetParent) || 0);
return (
elem.offsetTop + ((elem.offsetParent && getTop(elem.offsetParent)) || 0)
);
}
/**
@ -13,7 +15,9 @@ export function getTop(elem) {
* @param elem dom
* */
export function getLeft(elem) {
return elem.offsetLeft + (elem.offsetParent && getLeft(elem.offsetParent) || 0);
return (
elem.offsetLeft + ((elem.offsetParent && getLeft(elem.offsetParent)) || 0)
);
}
/**
@ -24,7 +28,9 @@ export function getLeft(elem) {
* @param handler 事件回调
* */
export function on(elem, events, handler) {
[].concat(events).forEach(event => elem.addEventListener(event, handler, false));
[]
.concat(events)
.forEach((event) => elem.addEventListener(event, handler, false));
}
/**
@ -36,10 +42,10 @@ export function on(elem, events, handler) {
* */
export function once(elem, events, handler) {
const listener = function (_this, args) {
handler.apply(_this, args)
handler.apply(_this, args);
off(elem, events, listener);
}
on(elem, events, listener)
};
on(elem, events, listener);
}
/**
@ -50,5 +56,7 @@ export function once (elem, events, handler) {
* @param handler 事件回调
* */
export function off(elem, events, handler) {
[].concat(events).forEach(event => elem.removeEventListener(event, handler, false));
[]
.concat(events)
.forEach((event) => elem.removeEventListener(event, handler, false));
}