38 lines
2.3 KiB
Vue
38 lines
2.3 KiB
Vue
<script setup lang="ts">
|
||
import { computed, ref, useId, watch } from 'vue'
|
||
|
||
const props = defineProps<{ codes: Array<string | null | undefined> }>()
|
||
const expanded = ref(false)
|
||
const listId = useId()
|
||
const codes = computed(() => [...new Set(props.codes.map(code => code?.trim()).filter((code): code is string => !!code))])
|
||
const visibleCodes = computed(() => expanded.value ? codes.value : codes.value.slice(0, 3))
|
||
watch(() => codes.value.join('\n'), () => { expanded.value = false })
|
||
</script>
|
||
|
||
<template>
|
||
<section class="inbound-codes" aria-label="关联入仓码">
|
||
<div class="codes-heading">
|
||
<span :title="`共 ${codes.length} 个入仓码`">入仓码 <span v-if="codes.length">({{ codes.length }} 个)</span></span>
|
||
<button v-if="codes.length > 3" type="button" :aria-expanded="expanded" :aria-controls="listId" @click="expanded = !expanded">
|
||
{{ expanded ? '收起' : `查看全部(还有 ${codes.length - 3} 个)` }}
|
||
</button>
|
||
</div>
|
||
<ul v-if="codes.length" :id="listId" class="codes-list" :class="{ expanded }" :tabindex="expanded ? 0 : undefined" aria-label="入仓码列表">
|
||
<li v-for="code in visibleCodes" :key="code" :title="code">{{ code }}</li>
|
||
</ul>
|
||
<span v-else class="codes-empty">—</span>
|
||
</section>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.inbound-codes { min-width: 0; margin: var(--admin-space-5) 0; font-size: var(--admin-font-body); }
|
||
.codes-heading { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--admin-space-3); color: var(--el-text-color-secondary); font-size: var(--admin-font-caption); }
|
||
.codes-heading button { border: 0; background: transparent; color: var(--el-color-primary); cursor: pointer; font: inherit; min-height: var(--admin-action-height); padding: 0; }
|
||
.codes-list { list-style: none; padding: 0; margin: var(--admin-space-1) 0 0; line-height: 1.8; }
|
||
.codes-list li { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||
.codes-list.expanded { max-height: 216px; overflow-y: auto; overscroll-behavior: contain; }
|
||
.codes-list.expanded li { white-space: normal; overflow-wrap: anywhere; }
|
||
.codes-heading button:focus-visible, .codes-list:focus-visible { outline: 2px solid var(--el-color-primary); outline-offset: 2px; }
|
||
.codes-empty { display: block; margin-top: var(--admin-space-1); }
|
||
</style>
|