🌀(lint): fix linter

This commit is contained in:
sight 2022-06-22 13:11:11 +08:00
parent 753f0f545b
commit 5acc9907a0
3 changed files with 102 additions and 65 deletions

View File

@ -1,5 +1,9 @@
<template> <template>
<lay-dropdown class="layui-cascader" ref="dropdownRef" :autoFitMinWidth="false"> <lay-dropdown
class="layui-cascader"
ref="dropdownRef"
:autoFitMinWidth="false"
>
<lay-input <lay-input
v-model="displayValue" v-model="displayValue"
readonly readonly

View File

@ -6,7 +6,15 @@ export default {
<script setup lang="ts"> <script setup lang="ts">
import "./index.less"; import "./index.less";
import { CSSProperties, nextTick, provide, ref, shallowRef, watch, watchEffect } from "vue"; import {
CSSProperties,
nextTick,
provide,
ref,
shallowRef,
watch,
watchEffect,
} from "vue";
import { onClickOutside, useWindowSize } from "@vueuse/core"; import { onClickOutside, useWindowSize } from "@vueuse/core";
import { DropdownTrigger, dropdownPlacement } from "./interface"; import { DropdownTrigger, dropdownPlacement } from "./interface";
@ -22,7 +30,7 @@ export interface LayDropdownProps {
const props = withDefaults(defineProps<LayDropdownProps>(), { const props = withDefaults(defineProps<LayDropdownProps>(), {
trigger: "click", trigger: "click",
disabled: false, disabled: false,
placement: 'bottom-left', placement: "bottom-left",
autoFitPlacement: true, autoFitPlacement: true,
autoFitMinWidth: true, autoFitMinWidth: true,
autoFitWidth: false, autoFitWidth: false,
@ -38,7 +46,7 @@ const contentSpace = 2;
const emit = defineEmits(["open", "hide"]); const emit = defineEmits(["open", "hide"]);
onClickOutside(dropdownRef, () => { onClickOutside(dropdownRef, () => {
changeVisible(false) changeVisible(false);
}); });
const open = (): void => { const open = (): void => {
@ -70,20 +78,17 @@ const changeVisible = (visible: boolean) => {
nextTick(() => { nextTick(() => {
updateContentStyle(); updateContentStyle();
}); });
} };
const updateContentStyle = () => { const updateContentStyle = () => {
if (!dropdownRef.value || !contentRef.value) { if (!dropdownRef.value || !contentRef.value) {
return return;
} }
const triggerRect = dropdownRef.value.getBoundingClientRect() const triggerRect = dropdownRef.value.getBoundingClientRect();
const contentRect = contentRef.value.getBoundingClientRect() const contentRect = contentRef.value.getBoundingClientRect();
const { style } = getContentStyle( const { style } = getContentStyle(props.placement, triggerRect, contentRect, {
props.placement, autoFitPlacement: props.autoFitPlacement,
triggerRect, });
contentRect,
{autoFitPlacement: props.autoFitPlacement}
);
if (props.autoFitMinWidth) { if (props.autoFitMinWidth) {
style.minWidth = `${triggerRect.width}px`; style.minWidth = `${triggerRect.width}px`;
@ -92,8 +97,8 @@ const updateContentStyle = () => {
style.width = `${triggerRect.width}px`; style.width = `${triggerRect.width}px`;
} }
contentStyle.value = style contentStyle.value = style;
} };
const getContentStyle = ( const getContentStyle = (
placement: dropdownPlacement, placement: dropdownPlacement,
@ -101,15 +106,21 @@ const getContentStyle = (
contentRect: DOMRect, contentRect: DOMRect,
{ {
autoFitPlacement = false, autoFitPlacement = false,
customStyle = {} customStyle = {},
}: { }: {
autoFitPlacement?: boolean; autoFitPlacement?: boolean;
customStyle?: CSSProperties; customStyle?: CSSProperties;
} = {} } = {}
) => { ) => {
let { top, left } = getContentOffset(placement, triggerRect, contentRect) let { top, left } = getContentOffset(placement, triggerRect, contentRect);
if (autoFitPlacement) { if (autoFitPlacement) {
const { top: fitTop, left: fitLeft } = getFitPlacement(top, left, placement, triggerRect, contentRect) const { top: fitTop, left: fitLeft } = getFitPlacement(
top,
left,
placement,
triggerRect,
contentRect
);
top = fitTop; top = fitTop;
left = fitLeft; left = fitLeft;
} }
@ -117,11 +128,11 @@ const getContentStyle = (
top: `${top}px`, top: `${top}px`,
left: `${left}px`, left: `${left}px`,
...customStyle, ...customStyle,
} };
return { return {
style style,
} };
} };
const getFitPlacement = ( const getFitPlacement = (
top: number, top: number,
@ -132,45 +143,49 @@ const getFitPlacement = (
) => { ) => {
// //
if (triggerRect.bottom + contentRect.height > windowHeight.value) { if (triggerRect.bottom + contentRect.height > windowHeight.value) {
top = -contentRect.height - contentSpace top = -contentRect.height - contentSpace;
} }
// //
if (triggerRect.top - contentRect.height < 0) { if (triggerRect.top - contentRect.height < 0) {
top = triggerRect.height + contentSpace top = triggerRect.height + contentSpace;
} }
if (["bottom-right", "top-right"].includes(placement)) { if (["bottom-right", "top-right"].includes(placement)) {
// //
const contentRectLeft = triggerRect.left - (contentRect.width - triggerRect.width) const contentRectLeft =
triggerRect.left - (contentRect.width - triggerRect.width);
if (contentRectLeft < 0) { if (contentRectLeft < 0) {
left = left + (0 - contentRectLeft) left = left + (0 - contentRectLeft);
} }
} }
if (["bottom-left", "top-left"].includes(placement)) { if (["bottom-left", "top-left"].includes(placement)) {
// //
const contentRectRight = triggerRect.right + (contentRect.width - triggerRect.width) const contentRectRight =
triggerRect.right + (contentRect.width - triggerRect.width);
if (contentRectRight > windowWidth.value) { if (contentRectRight > windowWidth.value) {
left = left - (contentRectRight - windowWidth.value) left = left - (contentRectRight - windowWidth.value);
} }
} }
if (["bottom", "top"].includes(placement)) { if (["bottom", "top"].includes(placement)) {
const contentRectLeft = triggerRect.left - (contentRect.width - triggerRect.width) / 2 const contentRectLeft =
const contentRectRight = triggerRect.right + (contentRect.width - triggerRect.width) / 2 triggerRect.left - (contentRect.width - triggerRect.width) / 2;
const contentRectRight =
triggerRect.right + (contentRect.width - triggerRect.width) / 2;
// //
if (contentRectLeft < 0) { if (contentRectLeft < 0) {
left = left + (0 - contentRectLeft) left = left + (0 - contentRectLeft);
} }
// //
if (contentRectRight > windowWidth.value) { if (contentRectRight > windowWidth.value) {
left = left - (contentRectRight - windowWidth.value) left = left - (contentRectRight - windowWidth.value);
} }
} }
return { return {
top, top,
left left,
} };
} };
const getContentOffset = ( const getContentOffset = (
placement: dropdownPlacement, placement: dropdownPlacement,
@ -181,40 +196,40 @@ const getContentOffset = (
case "top": case "top":
return { return {
top: -contentRect.height - contentSpace, top: -contentRect.height - contentSpace,
left: -(contentRect.width - triggerRect.width) / 2 left: -(contentRect.width - triggerRect.width) / 2,
} };
case "top-left": case "top-left":
return { return {
top: -contentRect.height - contentSpace, top: -contentRect.height - contentSpace,
left: 0 left: 0,
} };
case "top-right": case "top-right":
return { return {
top: -contentRect.height - contentSpace, top: -contentRect.height - contentSpace,
left: -(contentRect.width - triggerRect.width) left: -(contentRect.width - triggerRect.width),
} };
case "bottom": case "bottom":
return { return {
top: triggerRect.height + contentSpace, top: triggerRect.height + contentSpace,
left: -(contentRect.width - triggerRect.width) / 2 left: -(contentRect.width - triggerRect.width) / 2,
} };
case "bottom-left": case "bottom-left":
return { return {
top: triggerRect.height + contentSpace, top: triggerRect.height + contentSpace,
left: 0 left: 0,
} };
case "bottom-right": case "bottom-right":
return { return {
top: triggerRect.height + contentSpace, top: triggerRect.height + contentSpace,
left: -(contentRect.width - triggerRect.width) left: -(contentRect.width - triggerRect.width),
} };
default: default:
return { return {
left: 0, left: 0,
top: 0, top: 0,
}; };
} }
} };
provide("openState", openState); provide("openState", openState);
@ -222,12 +237,24 @@ defineExpose({ open, hide, toggle });
</script> </script>
<template> <template>
<div ref="dropdownRef" class="layui-dropdown" @mouseenter="trigger == 'hover' && open()" <div
@mouseleave="trigger == 'hover' && hide()" :class="{ 'layui-dropdown-up': openState }"> ref="dropdownRef"
<div @click="trigger == 'click' && toggle()" @contextmenu.prevent="trigger == 'contextMenu' && toggle()"> class="layui-dropdown"
@mouseenter="trigger == 'hover' && open()"
@mouseleave="trigger == 'hover' && hide()"
:class="{ 'layui-dropdown-up': openState }"
>
<div
@click="trigger == 'click' && toggle()"
@contextmenu.prevent="trigger == 'contextMenu' && toggle()"
>
<slot></slot> <slot></slot>
</div> </div>
<dl ref="contentRef" class="layui-anim layui-anim-upbit" :style="contentStyle"> <dl
ref="contentRef"
class="layui-anim layui-anim-upbit"
:style="contentStyle"
>
<slot name="content"></slot> <slot name="content"></slot>
</dl> </dl>
</div> </div>

View File

@ -1,2 +1,8 @@
export type DropdownTrigger = "click" | "hover" | "contextMenu"; export type DropdownTrigger = "click" | "hover" | "contextMenu";
export type dropdownPlacement = 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right'; export type dropdownPlacement =
| "top"
| "top-left"
| "top-right"
| "bottom"
| "bottom-left"
| "bottom-right";