feat: move filter chips to bottom of note list with gradient fade

Move FilterPills and InboxFilterPills from the top (below header) to
a floating position at the bottom of the note list. When position is
"bottom", pills are absolutely positioned with a gradient background
(transparent → card color) to create a "floating above content"
effect. Pills are centered with gap-2 and wrap to multiple lines.
Matches the ui-design.pen "Filter Pills Bar" frame.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Test
2026-03-31 11:38:13 +02:00
parent 517f1c04f5
commit e43e2a7549
3 changed files with 27 additions and 7 deletions

View File

@@ -5,6 +5,7 @@ interface FilterPillsProps {
active: NoteListFilter
counts: Record<NoteListFilter, number>
onChange: (filter: NoteListFilter) => void
position?: 'top' | 'bottom'
}
const PILLS: { value: NoteListFilter; label: string }[] = [
@@ -13,9 +14,18 @@ const PILLS: { value: NoteListFilter; label: string }[] = [
{ value: 'trashed', label: 'Trashed' },
]
function FilterPillsInner({ active, counts, onChange }: FilterPillsProps) {
const BOTTOM_GRADIENT = 'linear-gradient(to bottom, transparent 0%, var(--card, #fff) 30%, var(--card, #fff) 100%)'
function FilterPillsInner({ active, counts, onChange, position = 'top' }: FilterPillsProps) {
const isBottom = position === 'bottom'
return (
<div className="flex h-auto min-h-[45px] shrink-0 flex-wrap items-center gap-1 border-b border-border px-4 py-1.5" data-testid="filter-pills">
<div
className={isBottom
? 'absolute bottom-0 left-0 right-0 z-10 flex flex-wrap items-center justify-center gap-2 px-4 py-3'
: 'flex h-auto min-h-[45px] shrink-0 flex-wrap items-center gap-1 border-b border-border px-4 py-1.5'}
style={isBottom ? { background: BOTTOM_GRADIENT } : undefined}
data-testid="filter-pills"
>
{PILLS.map(({ value, label }) => (
<button
key={value}

View File

@@ -5,6 +5,7 @@ interface InboxFilterPillsProps {
active: InboxPeriod
counts: Record<InboxPeriod, number>
onChange: (period: InboxPeriod) => void
position?: 'top' | 'bottom'
}
const PILLS: { value: InboxPeriod; label: string }[] = [
@@ -14,9 +15,18 @@ const PILLS: { value: InboxPeriod; label: string }[] = [
{ value: 'all', label: 'All' },
]
function InboxFilterPillsInner({ active, counts, onChange }: InboxFilterPillsProps) {
const BOTTOM_GRADIENT = 'linear-gradient(to bottom, transparent 0%, var(--card, #fff) 30%, var(--card, #fff) 100%)'
function InboxFilterPillsInner({ active, counts, onChange, position = 'top' }: InboxFilterPillsProps) {
const isBottom = position === 'bottom'
return (
<div className="flex h-auto min-h-[45px] shrink-0 flex-wrap items-center gap-1 border-b border-border px-4 py-1.5" data-testid="inbox-filter-pills">
<div
className={isBottom
? 'absolute bottom-0 left-0 right-0 z-10 flex flex-wrap items-center justify-center gap-2 px-4 py-3'
: 'flex h-auto min-h-[45px] shrink-0 flex-wrap items-center gap-1 border-b border-border px-4 py-1.5'}
style={isBottom ? { background: BOTTOM_GRADIENT } : undefined}
data-testid="inbox-filter-pills"
>
{PILLS.map(({ value, label }) => (
<button
key={value}