From 84653837a023d15a49fb1df3a2ded376b68801f5 Mon Sep 17 00:00:00 2001 From: Till JS Date: Tue, 31 Mar 2026 13:14:57 +0200 Subject: [PATCH] refactor(todo): replace Mehr dropdown with inline project pills, add Filter label - Add "Filter:" label pill before priority filter pills - Replace Mehr dropdown with inline project pills (colored, toggleable) - Add dividers between sections (tags | filter/priorities | projects | sort) - Remove unused dropdown code and DotsThree import Co-Authored-By: Claude Opus 4.6 (1M context) --- .../web/src/lib/components/TaskFilters.svelte | 167 +++++------------- 1 file changed, 46 insertions(+), 121 deletions(-) diff --git a/apps/todo/apps/web/src/lib/components/TaskFilters.svelte b/apps/todo/apps/web/src/lib/components/TaskFilters.svelte index 00245983a..8bc934cd3 100644 --- a/apps/todo/apps/web/src/lib/components/TaskFilters.svelte +++ b/apps/todo/apps/web/src/lib/components/TaskFilters.svelte @@ -10,14 +10,7 @@ const tagsCtx: { readonly value: Tag[] } = getContext('tags'); import type { SortBy, SortOrder } from '$lib/stores/view.svelte'; - import { - CaretDown, - Check, - CheckCircle, - DotsThree, - MagnifyingGlass, - X, - } from '@manacore/shared-icons'; + import { CaretDown, Check, CheckCircle, MagnifyingGlass, X } from '@manacore/shared-icons'; interface Props { // Layout @@ -90,7 +83,6 @@ ]; // Dropdown states - let showFilterDropdown = $state(false); let showLabelsDropdown = $state(false); let hasActiveFilters = $derived( @@ -115,14 +107,8 @@ onLabelsChange([...selectedLabelIds, labelId]); } } - - function closeFilterDropdown() { - showFilterDropdown = false; - } - - {#if variant === 'strip'}
@@ -161,6 +147,11 @@ {/if} + + + Filter: + + {#each priorities as priority (priority.value)} + {/each} + {/if} + {#if showSort && onSortChange} + {#each sortOptions as option (option.id)} {/if} - - -
e.stopPropagation()}> - - - {#if showFilterDropdown} -
e.stopPropagation()}> -
-
Projekt
- -
-
- {/if} -
{:else} @@ -559,6 +538,28 @@ background: rgba(255, 255, 255, 0.15); } + /* Project pills */ + .project-pill .project-dot { + width: 10px; + height: 10px; + border-radius: 50%; + background-color: var(--project-color); + flex-shrink: 0; + } + + .project-pill.selected { + background: var(--project-color) !important; + border-color: var(--project-color) !important; + } + + .project-pill.selected .project-dot { + background-color: white; + } + + .project-pill.selected .pill-label { + color: white; + } + /* Priority pills */ .priority-pill.selected { background: var(--priority-color) !important; @@ -613,82 +614,6 @@ pointer-events: none; } - /* Filter dropdown */ - .filter-dropdown-container { - position: relative; - display: flex; - align-items: center; - } - - .filter-dropdown { - position: absolute; - bottom: calc(100% + 0.5rem); - left: 50%; - transform: translateX(-50%); - min-width: 220px; - padding: 0.75rem; - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(12px); - -webkit-backdrop-filter: blur(12px); - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 0.75rem; - box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1); - z-index: 100; - } - - :global(.dark) .filter-dropdown { - background: rgba(30, 30, 30, 0.95); - border-color: rgba(255, 255, 255, 0.1); - } - - .filter-section { - margin-bottom: 0.75rem; - } - - .filter-section:last-child { - margin-bottom: 0; - } - - .filter-section-header { - font-size: 0.6875rem; - font-weight: 600; - color: #6b7280; - text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: 0.5rem; - } - - :global(.dark) .filter-section-header { - color: #9ca3af; - } - - .filter-select { - width: 100%; - padding: 0.5rem 0.75rem; - font-size: 0.8125rem; - color: #374151; - background: rgba(0, 0, 0, 0.05); - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 0.5rem; - cursor: pointer; - transition: border-color 0.15s; - } - - :global(.dark) .filter-select { - color: #f3f4f6; - background: rgba(255, 255, 255, 0.1); - border-color: rgba(255, 255, 255, 0.1); - } - - .filter-select:hover { - border-color: rgba(139, 92, 246, 0.5); - } - - .filter-select:focus { - outline: none; - border-color: #8b5cf6; - } - /* Responsive strip */ @media (max-width: 640px) { .filter-strip-wrapper {