feat: add search panel
This commit is contained in:
24
frontend/superadmin/src/components/SearchField.vue
Normal file
24
frontend/superadmin/src/components/SearchField.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
label: { type: String, required: true },
|
||||
forId: { type: String, default: '' },
|
||||
colClass: { type: String, default: 'col-span-12 md:col-span-6 lg:col-span-4' },
|
||||
labelClass: { type: String, default: 'w-28 text-right' }
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="props.colClass">
|
||||
<div class="flex items-center gap-3">
|
||||
<label v-if="props.forId" :for="props.forId"
|
||||
class="text-sm font-medium text-surface-900 dark:text-surface-0" :class="props.labelClass">
|
||||
{{ props.label }}
|
||||
</label>
|
||||
<span v-else class="text-sm font-medium text-surface-900 dark:text-surface-0" :class="props.labelClass">{{
|
||||
props.label }}</span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
44
frontend/superadmin/src/components/SearchPanel.vue
Normal file
44
frontend/superadmin/src/components/SearchPanel.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<script setup>
|
||||
import { Comment, computed, ref, useSlots } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
collapsedCount: { type: Number, default: 3 },
|
||||
initialExpanded: { type: Boolean, default: false },
|
||||
loading: { type: Boolean, default: false }
|
||||
});
|
||||
|
||||
const emit = defineEmits(['search', 'reset']);
|
||||
|
||||
const slots = useSlots();
|
||||
const expanded = ref(props.initialExpanded);
|
||||
|
||||
const fieldNodes = computed(() => {
|
||||
const nodes = slots.default ? slots.default() : [];
|
||||
return (nodes || []).filter((n) => n && n.type !== Comment);
|
||||
});
|
||||
|
||||
const canToggle = computed(() => fieldNodes.value.length > props.collapsedCount);
|
||||
const visibleFields = computed(() => (expanded.value ? fieldNodes.value : fieldNodes.value.slice(0, props.collapsedCount)));
|
||||
|
||||
function onToggle() {
|
||||
expanded.value = !expanded.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mb-4 p-4 rounded border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-900">
|
||||
<div class="flex flex-col lg:flex-row lg:items-end gap-4 lg:gap-6">
|
||||
<div class="flex-1 grid grid-cols-12 gap-x-6 gap-y-4 items-end">
|
||||
<template v-for="(node, idx) in visibleFields" :key="idx">
|
||||
<component :is="node" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end gap-2 lg:flex-none">
|
||||
<Button label="查询" icon="pi pi-search" :loading="props.loading" @click="emit('search')" />
|
||||
<Button label="重置" icon="pi pi-refresh" severity="secondary" outlined :disabled="props.loading" @click="emit('reset')" />
|
||||
<Button v-if="canToggle" :label="expanded ? '收起' : '展开'" :icon="expanded ? 'pi pi-angle-up' : 'pi pi-angle-down'" iconPos="right" severity="secondary" text :disabled="props.loading" @click="onToggle" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user