feat(activities): UI tweaks across feed, detail, hosting, calendar, scan, shell #91

Merged
padreug merged 25 commits from feat/ui-tweaks into dev 2026-06-10 16:35:50 +00:00
Showing only changes of commit d92690d3f1 - Show all commits

feat(activities): stationary Filters column next to scrolling pills

Filters icon + Clear-all sit in a stationary left-aligned column;
only the All/Today/Tomorrow/etc temporal pills scroll horizontally.
Clear-all is tucked tightly under the Filters icon (h-5, 10px text,
gap-0.5) and shows only when a filter is active. The badge no
longer lives inside the overflow-x scroll container, so the count
chip isn't clipped at the corner anymore.
Padreug 2026-06-04 22:06:02 +02:00 committed by padreug

View file

@ -9,7 +9,7 @@ import {
CollapsibleTrigger, CollapsibleTrigger,
} from '@/components/ui/collapsible' } from '@/components/ui/collapsible'
import { Separator } from '@/components/ui/separator' import { Separator } from '@/components/ui/separator'
import { SlidersHorizontal, ChevronDown, History } from 'lucide-vue-next' import { SlidersHorizontal, History } from 'lucide-vue-next'
import { useEvents } from '../composables/useEvents' import { useEvents } from '../composables/useEvents'
import EventSearchOverlay from '../components/EventSearchOverlay.vue' import EventSearchOverlay from '../components/EventSearchOverlay.vue'
import TemporalFilterBar from '../components/TemporalFilterBar.vue' import TemporalFilterBar from '../components/TemporalFilterBar.vue'
@ -77,45 +77,47 @@ function handleSelectEvent(event: Event) {
<DatePickerStrip :selected-date="selectedDate" @select="selectDate" /> <DatePickerStrip :selected-date="selectedDate" @select="selectDate" />
</div> </div>
<!-- Temporal filter pills --> <!-- Filters trigger + Clear-all stay stationary in a left-aligned
<div class="mb-3"> column; only the temporal pills scroll horizontally. The
<TemporalFilterBar :model-value="temporal" @update:model-value="setTemporal" /> Filters icon (with a count badge when past-events or any
</div> categories are active) opens a collapsible that hosts the
past-events toggle + category chips below. -->
<!-- Filters collapsible (categories + past-events). Past events used <Collapsible v-model:open="filtersOpen" class="mb-3">
to live on its own row above the trigger; folded in here so the <div class="flex items-start gap-3">
feed gets that vertical real estate by default. The Clear-all <div class="shrink-0 flex flex-col items-center gap-0.5">
affordance shares the trigger row when any filter is active so
the old "Filters active" notice doesn't claim another row. -->
<Collapsible v-model:open="filtersOpen" class="mb-4">
<div class="flex items-center gap-1">
<CollapsibleTrigger as-child> <CollapsibleTrigger as-child>
<Button variant="ghost" size="sm" class="gap-1.5 px-2 text-muted-foreground"> <Button
variant="ghost"
size="icon"
class="rounded-full h-8 w-8 relative"
:class="{ 'bg-accent text-accent-foreground': filtersOpen || filterCount > 0 }"
:aria-label="t('events.filters.filters', 'Filters')"
:aria-expanded="filtersOpen"
>
<SlidersHorizontal class="w-4 h-4" /> <SlidersHorizontal class="w-4 h-4" />
{{ t('events.filters.filters', 'Filters') }}
<span <span
v-if="filterCount > 0" v-if="filterCount > 0"
class="text-xs bg-primary text-primary-foreground rounded-full px-1.5" class="absolute -top-1 -right-1 min-w-[16px] h-[16px] px-1 rounded-full bg-primary text-primary-foreground text-[10px] font-semibold flex items-center justify-center"
> >
{{ filterCount }} {{ filterCount }}
</span> </span>
<ChevronDown
class="w-3.5 h-3.5 transition-transform"
:class="{ 'rotate-180': filtersOpen }"
/>
</Button> </Button>
</CollapsibleTrigger> </CollapsibleTrigger>
<Button <Button
v-if="hasActiveFilters" v-if="hasActiveFilters"
variant="ghost" variant="ghost"
size="sm" size="sm"
class="h-7 px-2 text-xs text-muted-foreground" class="h-5 px-1 text-[10px] text-muted-foreground"
@click="resetFilters" @click="resetFilters"
> >
{{ t('events.filters.clearAll', 'Clear all') }} {{ t('events.filters.clearAll', 'Clear all') }}
</Button> </Button>
</div> </div>
<CollapsibleContent class="mt-2 space-y-3"> <div class="flex-1 min-w-0 pt-0.5">
<TemporalFilterBar :model-value="temporal" @update:model-value="setTemporal" />
</div>
</div>
<CollapsibleContent class="mt-3 space-y-3">
<Button <Button
:variant="showPast ? 'default' : 'outline'" :variant="showPast ? 'default' : 'outline'"
size="sm" size="sm"