This commit is contained in:
2026-08-10 16:24:54 +08:00
parent e119b48662
commit 820432a381
52 changed files with 1015 additions and 705 deletions
+23 -4
View File
@@ -1,21 +1,40 @@
<script setup lang="ts">
import { Comment, Fragment, Text, isVNode, useSlots } from 'vue'
withDefaults(defineProps<{
ariaLabel?: string
}>(), {
ariaLabel: '列表页面',
})
const slots = useSlots()
type RegionName = 'toolbar' | 'metrics' | 'state' | 'default'
function hasRenderableContent(value: unknown): boolean {
if (Array.isArray(value)) return value.some(hasRenderableContent)
if (!isVNode(value)) return typeof value === 'string' ? value.trim().length > 0 : value != null && typeof value !== 'boolean'
if (value.type === Comment) return false
if (value.type === Text) return hasRenderableContent(value.children)
if (value.type === Fragment) return hasRenderableContent(value.children)
return true
}
function hasRegion(name: RegionName) {
return hasRenderableContent(slots[name]?.())
}
</script>
<template>
<section class="list-page-layout" :aria-label="ariaLabel">
<div v-if="$slots.toolbar" class="list-page-layout__toolbar"><slot name="toolbar" /></div>
<div v-if="$slots.metrics" class="list-page-layout__metrics"><slot name="metrics" /></div>
<div v-if="$slots.state" class="list-page-layout__state"><slot name="state" /></div>
<div v-if="$slots.default" class="list-page-layout__content"><slot /></div>
<div v-if="hasRegion('toolbar')" class="list-page-layout__toolbar"><slot name="toolbar" /></div>
<div v-if="hasRegion('metrics')" class="list-page-layout__metrics"><slot name="metrics" /></div>
<div v-if="hasRegion('state')" class="list-page-layout__state"><slot name="state" /></div>
<div v-if="hasRegion('default')" class="list-page-layout__content"><slot /></div>
</section>
</template>
<style scoped>
.list-page-layout { display: flex; min-width: 0; flex-direction: column; gap: 16px; }
.list-page-layout__toolbar, .list-page-layout__metrics, .list-page-layout__state, .list-page-layout__content { min-width: 0; }
.list-page-layout__toolbar:empty, .list-page-layout__metrics:empty, .list-page-layout__state:empty, .list-page-layout__content:empty { display: none; }
</style>