|
|
@@ -1,39 +1,43 @@
|
|
|
<template>
|
|
|
- <div class="flex flex-col" :style="{ height }">
|
|
|
- <!-- header -->
|
|
|
- <div
|
|
|
- class="h-32px bg-bg-tertiary flex items-center justify-between px-1 cursor-pointer border-b-1px border-b-solid border-border"
|
|
|
- @click="parent?.change(name)"
|
|
|
- >
|
|
|
- <div class="left">
|
|
|
- <span class="mr-8px text-text-secondary">
|
|
|
- <ai-outline-down :size="12" v-if="opened" />
|
|
|
- <ai-outline-right :size="12" v-else />
|
|
|
- </span>
|
|
|
- <span class="text-14px text-text-secondary">{{ title }}</span>
|
|
|
+ <SplitterPanel collapsible :collapsed-size="0" ref="splitterPanelRef" style="min-height: 32px">
|
|
|
+ <template #default="{ isExpanded, collapse, expand }">
|
|
|
+ <div class="w-full h-full flex flex-col">
|
|
|
+ <!-- header -->
|
|
|
+ <div
|
|
|
+ class="h-32px bg-bg-tertiary flex items-center justify-between px-1 cursor-pointer border-b-1px border-b-solid border-border"
|
|
|
+ @click="isExpanded ? collapse() : expand()"
|
|
|
+ >
|
|
|
+ <div class="left">
|
|
|
+ <span class="mr-8px text-text-secondary">
|
|
|
+ <ai-outline-down :size="12" v-if="isExpanded" />
|
|
|
+ <ai-outline-right :size="12" v-else />
|
|
|
+ </span>
|
|
|
+ <span class="text-14px text-text-secondary">{{ title }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="right">
|
|
|
+ <slot name="header-right"></slot>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- content -->
|
|
|
+ <div class="flex-1 overflow-y-auto" v-show="isExpanded">
|
|
|
+ <slot></slot>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <div class="right">
|
|
|
- <slot name="header-right"></slot>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- content -->
|
|
|
- <div class="flex-1" v-show="opened">
|
|
|
- <slot></slot>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
+ </SplitterPanel>
|
|
|
+ <SplitterResizeHandle class="splitter-handle" />
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { defineProps, defineEmits, computed, inject, ref, withDefaults } from 'vue'
|
|
|
+import { defineProps, defineEmits, withDefaults } from 'vue'
|
|
|
import { AiOutlineRight, AiOutlineDown } from 'vue-icons-plus/ai'
|
|
|
-import type { Ref } from 'vue'
|
|
|
+import { SplitterPanel, SplitterResizeHandle } from 'reka-ui'
|
|
|
|
|
|
-const HEADER_HEIGHT = 32
|
|
|
-const props = withDefaults(
|
|
|
+withDefaults(
|
|
|
defineProps<{
|
|
|
- name: string
|
|
|
title: string
|
|
|
min?: number
|
|
|
+ expand?: boolean
|
|
|
}>(),
|
|
|
{
|
|
|
min: 0
|
|
|
@@ -41,23 +45,6 @@ const props = withDefaults(
|
|
|
)
|
|
|
|
|
|
const emit = defineEmits(['change'])
|
|
|
-const parent = inject<{
|
|
|
- actives: Ref<string[]>
|
|
|
- change: (name?: string) => void
|
|
|
- lastChildName: string
|
|
|
-}>('info')
|
|
|
-
|
|
|
-const size = ref<number>(props.min)
|
|
|
-
|
|
|
-const height = computed(() => {
|
|
|
- return `${opened.value ? Math.max(size.value, HEADER_HEIGHT) : HEADER_HEIGHT}px`
|
|
|
-})
|
|
|
-
|
|
|
-// 展开状态
|
|
|
-const opened = computed(() => {
|
|
|
- const { actives } = parent || {}
|
|
|
- return props.name && actives?.value?.includes(props.name)
|
|
|
-})
|
|
|
</script>
|
|
|
|
|
|
<style scoped></style>
|