add result panel.

This commit is contained in:
2023-01-10 16:16:14 +08:00
parent a3456595a5
commit e3db109317
22 changed files with 714 additions and 172 deletions

View File

@@ -0,0 +1,140 @@
<template>
<div
:style="{ cursor, userSelect }"
class="vue-splitter-container clearfix"
@mouseup="onMouseUp"
@mousemove="onMouseMove"
>
<Pane
class="splitter-pane splitter-paneL"
:split="split"
:style="{ [type]: percent + '%' }"
>
<slot name="panel"></slot>
</Pane>
<Resizer
:className="className"
:style="{ [resizeType]: percent + '%' }"
:split="split"
@mousedown.native="onMouseDown"
@click.native="onClick"
></Resizer>
<Pane
class="splitter-pane splitter-paneR"
:split="split"
:style="{ [type]: 100 - percent + '%' }"
>
<slot name="paner"></slot>
</Pane>
<div class="vue-splitter-container-mask" v-if="active"></div>
</div>
</template>
<script setup lang="ts">
import Resizer from "./resizer.vue"
import Pane from "./pane.vue"
import { computed, ref } from "vue"
const {
minPercent = 10,
defaultPercent = 50,
split,
className,
} = defineProps<{
minPercent?: number
defaultPercent?: number
split: "vertical" | "horizontal"
className?: string
}>()
const emit = defineEmits(["resize"])
const active = ref(false)
const hasMoved = ref(false)
const percent = ref(defaultPercent)
const type = ref(split === "vertical" ? "width" : "height")
const resizeType = ref(split === "vertical" ? "left" : "top")
const userSelect = computed(() => (active.value ? "none" : "auto"))
const cursor = computed(() =>
active.value ? (split === "vertical" ? "col-resize" : "row-resize") : ""
)
// watch(
// () => defaultPercent,
// (newValue) => {
// percent.value = newValue
// }
// )
function onClick() {
if (!hasMoved.value) {
percent.value = 50
emit("resize", percent.value)
}
}
function onMouseDown() {
active.value = true
hasMoved.value = false
}
function onMouseUp() {
active.value = false
}
function onMouseMove(e: any) {
if (e.buttons === 0) {
active.value = false
}
if (active.value) {
let offset = 0
let target = e.currentTarget
if (split === "vertical") {
while (target) {
offset += target.offsetLeft
target = target.offsetParent
}
} else {
while (target) {
offset += target.offsetTop
target = target.offsetParent
}
}
const currentPage = split === "vertical" ? e.pageX : e.pageY
const targetOffset =
split === "vertical"
? e.currentTarget.offsetWidth
: e.currentTarget.offsetHeight
const newPercent =
Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100
if (newPercent > minPercent && newPercent < 100 - minPercent) {
percent.value = newPercent
}
emit("resize", newPercent)
hasMoved.value = true
}
}
</script>
<style scoped>
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.vue-splitter-container {
height: 100%;
position: relative;
}
.vue-splitter-container-mask {
z-index: 9999;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
</style>

View File

@@ -0,0 +1,40 @@
<template>
<div :class="classes">
<slot></slot>
</div>
</template>
<script setup lang="ts">
const { className, split } = defineProps<{
split: "horizontal" | "vertical"
className?: string
}>()
const classes = $computed(() => [split, className].join(" "))
</script>
<style scoped>
.splitter-pane.vertical.splitter-paneL {
position: absolute;
left: 0px;
height: 100%;
padding-right: 3px;
}
.splitter-pane.vertical.splitter-paneR {
position: absolute;
right: 0px;
height: 100%;
padding-left: 3px;
}
.splitter-pane.horizontal.splitter-paneL {
position: absolute;
top: 0px;
width: 100%;
}
.splitter-pane.horizontal.splitter-paneR {
position: absolute;
bottom: 0px;
width: 100%;
padding-top: 3px;
}
</style>

View File

@@ -0,0 +1,43 @@
<template>
<div :class="classes"></div>
</template>
<script setup lang="ts">
import { computed } from "vue"
const { className, split } = defineProps<{
split: "horizontal" | "vertical"
className?: string
}>()
const classes = computed(() =>
["splitter-pane-resizer", split, className].join(" ")
)
</script>
<style scoped>
.splitter-pane-resizer {
box-sizing: border-box;
background: #000;
position: absolute;
opacity: 0.2;
z-index: 1;
background-clip: padding-box;
}
.splitter-pane-resizer.horizontal {
height: 11px;
margin: -5px 0;
border-top: 5px solid rgba(255, 255, 255, 0);
border-bottom: 5px solid rgba(255, 255, 255, 0);
cursor: row-resize;
width: 100%;
}
.splitter-pane-resizer.vertical {
width: 11px;
height: 100%;
margin-left: -5px;
border-left: 5px solid rgba(255, 255, 255, 0);
border-right: 5px solid rgba(255, 255, 255, 0);
cursor: col-resize;
}
</style>

View File

@@ -1,8 +1,8 @@
import { useToggle } from "@vueuse/core"
import { defineStore } from "pinia"
import { ref } from "vue"
export const useLoginStore = defineStore("login", () => {
const visible = ref(false)
const [visible] = useToggle()
function show() {
visible.value = true