chore(fc2a): polish pass — toasts, loading skeletons, focus guards, mobile breakpoints
AppSnackbar mounts once at the app root and exposes a window.__fcToast function the stores call from error paths. This avoids prop-drilling a toast emitter through every component while keeping the snackbar component itself testable in isolation. GalleryGrid renders shimmer-skeleton placeholders on initial load so the first paint isn't empty. Skeleton uses the same auto-fill grid columns as the real items so layout doesn't shift when content arrives. Modal arrow nav now ignores text-entry elements so typing in the tag autocomplete doesn't navigate prev/next. Small-screen breakpoint (<600px) tightens gallery thumbnails to 120px min. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="fc-gallery-grid">
|
||||
<div v-if="store.loading && store.images.length === 0" class="fc-gallery-grid__skeleton">
|
||||
<div v-for="i in 12" :key="i" class="fc-gallery-grid__skeleton-item" />
|
||||
</div>
|
||||
<template v-for="group in store.dateGroups" :key="`${group.year}-${group.month}`">
|
||||
<h2 class="fc-gallery-grid__date-header" :id="dateHeaderId(group)">
|
||||
{{ monthLabel(group.year, group.month) }}
|
||||
@@ -96,4 +99,33 @@ function imagesForGroup(group) {
|
||||
padding: 32px 0;
|
||||
color: rgb(var(--v-theme-on-surface-variant, var(--v-theme-on-surface)));
|
||||
}
|
||||
.fc-gallery-grid__skeleton {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
.fc-gallery-grid__skeleton-item {
|
||||
aspect-ratio: 1;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgb(var(--v-theme-surface)) 0%,
|
||||
rgb(var(--v-theme-surface-light)) 50%,
|
||||
rgb(var(--v-theme-surface)) 100%
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: fc-shimmer 1.4s infinite;
|
||||
border-radius: 4px;
|
||||
}
|
||||
@keyframes fc-shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.fc-gallery-grid__items,
|
||||
.fc-gallery-grid__skeleton {
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user