refactor(ui): CardHeading primitive for icon+title card/dialog headings (DRY pattern sweep)
The icon+title v-card-title heading (d-flex align-center + gap + <v-icon size=small> + <span>) was hand-rolled identically in 13 cards/dialogs (15 heading instances). Consolidate to <CardHeading icon title> (components/common) with an iconColor prop (error headings) and a default slot for trailing content (spacer+actions, inline status chip). Adopted everywhere the pattern appears — all-or-nothing per the hardened DRY process. Over-DRY guard: plain text-only <v-card-title> one-liners are NOT this pattern and stay; DownloadDetailModal leads with a status CHIP (not an icon), a different concept, left alone. §8b: the only remaining d-flex align-center v-card-title is that intentional variant. Catalog updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,10 +6,10 @@
|
||||
@update:model-value="$emit('update:modelValue', $event)"
|
||||
>
|
||||
<v-card v-if="source">
|
||||
<v-card-title class="d-flex align-center">
|
||||
<v-icon class="mr-2">mdi-eye-outline</v-icon>
|
||||
Preview · {{ source.artist_name }}
|
||||
</v-card-title>
|
||||
<CardHeading
|
||||
icon="mdi-eye-outline"
|
||||
:title="`Preview · ${source.artist_name}`"
|
||||
/>
|
||||
<v-card-subtitle class="fc-preview__url">{{ source.url }}</v-card-subtitle>
|
||||
|
||||
<v-card-text>
|
||||
@@ -70,6 +70,7 @@
|
||||
import { ref, watch } from 'vue'
|
||||
import { useSourcesStore } from '../../stores/sources.js'
|
||||
import { formatRelative } from '../../utils/date.js'
|
||||
import CardHeading from '../common/CardHeading.vue'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: Boolean, default: false },
|
||||
|
||||
Reference in New Issue
Block a user