79
src/components/map/GuidePoiSummaryCard.vue
Normal file
79
src/components/map/GuidePoiSummaryCard.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="guide-poi-card" :class="{ collapsed }">
|
||||
<view v-if="collapsible" class="poi-card-handle" @tap.stop="emit('toggle')"></view>
|
||||
|
||||
<view v-if="collapsed" class="poi-card-collapsed" @tap="emit('expand')">
|
||||
<view class="poi-card-copy">
|
||||
<text class="poi-card-title">{{ title }}</text>
|
||||
<text class="poi-card-subtitle">{{ subtitle }}</text>
|
||||
</view>
|
||||
<view class="poi-card-mini-action"><text class="poi-card-mini-text">展开</text></view>
|
||||
</view>
|
||||
|
||||
<template v-else>
|
||||
<view class="poi-card-header">
|
||||
<view class="poi-card-copy">
|
||||
<text class="poi-card-title">{{ title }}</text>
|
||||
<text v-if="subtitle" class="poi-card-subtitle">{{ subtitle }}</text>
|
||||
</view>
|
||||
<view class="poi-card-header-actions">
|
||||
<view v-if="collapsible" class="poi-card-soft-action" @tap="emit('collapse')"><text class="poi-card-soft-text">收起</text></view>
|
||||
<view class="poi-card-close" :data-testid="closeTestId" aria-label="关闭地点信息" @tap.stop="emit('close')"><text class="poi-card-close-text">×</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="metaItems.length" class="poi-card-meta" data-testid="facility-detail-meta">
|
||||
<view v-for="item in metaItems" :key="item.label" class="poi-card-meta-item">
|
||||
<text class="poi-card-meta-label">{{ item.label }}</text>
|
||||
<text class="poi-card-meta-value">{{ item.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text v-if="description" class="poi-card-description">{{ description }}</text>
|
||||
<view v-if="errorMessage" class="poi-card-error" data-testid="facility-location-error"><text class="poi-card-error-text">{{ errorMessage }}</text></view>
|
||||
<view v-if="actionText" class="poi-card-actions"><view class="poi-action primary" @tap="emit('action')"><text class="poi-action-text">{{ actionText }}</text></view></view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
interface GuidePoiSummaryMetaItem { label: string; value: string }
|
||||
|
||||
withDefaults(defineProps<{
|
||||
title: string
|
||||
subtitle?: string
|
||||
collapsed?: boolean
|
||||
collapsible?: boolean
|
||||
metaItems?: GuidePoiSummaryMetaItem[]
|
||||
description?: string
|
||||
errorMessage?: string
|
||||
actionText?: string
|
||||
closeTestId?: string
|
||||
}>(), {
|
||||
subtitle: '', collapsed: false, collapsible: false, metaItems: () => [], description: '', errorMessage: '', actionText: '', closeTestId: ''
|
||||
})
|
||||
|
||||
const emit = defineEmits<{ close: []; collapse: []; expand: []; toggle: []; action: [] }>()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.guide-poi-card { position: absolute; left: 12px; right: 12px; bottom: calc(env(safe-area-inset-bottom) + 24px); box-sizing: border-box; padding: 10px 14px 14px; background: rgba(255, 255, 255, 0.96); border: 1px solid #e5e6de; border-radius: 8px; box-shadow: 0 10px 24px rgba(36, 49, 42, 0.12); z-index: 1003; }
|
||||
.guide-poi-card.collapsed { padding: 8px 10px 10px; }
|
||||
.poi-card-handle { width: 38px; height: 4px; margin: 0 auto 10px; background: #d8dbd2; border-radius: 999px; }
|
||||
.poi-card-collapsed, .poi-card-header { display: flex; justify-content: space-between; gap: 10px; }
|
||||
.poi-card-collapsed { min-height: 44px; align-items: center; gap: 12px; }
|
||||
.poi-card-header { align-items: flex-start; }
|
||||
.poi-card-copy { min-width: 0; display: flex; flex: 1; flex-direction: column; gap: 3px; }
|
||||
.poi-card-title { overflow: hidden; color: #151713; font-size: 17px; font-weight: 700; line-height: 24px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.poi-card-subtitle, .poi-card-meta-label { color: #696962; font-size: 12px; line-height: 17px; }
|
||||
.poi-card-header-actions { display: flex; flex: 0 0 auto; gap: 6px; }
|
||||
.poi-card-soft-action, .poi-card-close, .poi-card-mini-action { display: flex; align-items: center; justify-content: center; border-radius: 8px; }
|
||||
.poi-card-soft-action, .poi-card-close { height: 28px; box-sizing: border-box; background: #f5f7f2; border: 1px solid #e4e5df; }
|
||||
.poi-card-soft-action { padding: 0 10px; }.poi-card-close { width: 28px; }.poi-card-soft-text { color: #545861; font-size: 12px; font-weight: 500; line-height: 16px; }.poi-card-close-text { color: #545861; font-size: 18px; line-height: 20px; }
|
||||
.poi-card-mini-action { height: 30px; padding: 0 10px; background: #151713; }.poi-card-mini-text { color: var(--museum-accent); font-size: 12px; font-weight: 500; line-height: 16px; }
|
||||
.poi-card-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
|
||||
.poi-card-meta-item { display: flex; min-width: 0; flex-direction: column; gap: 2px; padding: 8px 10px; box-sizing: border-box; background: #f7f8f3; border: 1px solid #e5e6de; border-radius: 8px; }
|
||||
.poi-card-meta-value { overflow: hidden; color: #1f2329; font-size: 14px; font-weight: 600; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.poi-card-description { display: block; margin-top: 10px; color: #424754; font-size: 13px; line-height: 19px; }.poi-card-error { margin-top: 10px; padding: 9px 10px; background: #fff4e8; border: 1px solid #f1c99e; border-radius: 8px; }.poi-card-error-text { color: #7a3e05; font-size: 13px; line-height: 18px; }
|
||||
.poi-card-actions { display: grid; grid-template-columns: minmax(0, 1fr); margin-top: 12px; }.poi-action { display: flex; align-items: center; justify-content: center; min-width: 0; height: 38px; padding: 0 16px; box-sizing: border-box; border: 1px solid #151713; border-radius: 8px; background: #151713; }.poi-action-text { color: var(--museum-accent); font-size: 12px; font-weight: 500; line-height: 16px; text-align: center; }
|
||||
@media (max-width: 360px) { .poi-card-meta { gap: 8px; } }
|
||||
</style>
|
||||
Reference in New Issue
Block a user