Skip to content

Commit e431588

Browse files
enkoclaude
andcommitted
refactor(frontend): Separate keyboard filter mode from regular dropdown
The keyboard filter modal and regular dropdown now use independent state: - Keyboard modal controlled by isFilterModeActive store - Regular dropdown controlled by local isOpen state - Escape handler handles each case separately This fixes the issue where the regular dropdown would appear after closing the keyboard filter modal, and removes the code smell of sharing state between two different UI modes. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 274d178 commit e431588

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

apps/frontend/src/lib/components/search/FacetDropdown.svelte

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,9 @@ let currentCategoryValues = $derived(
108108
$filterModeCategory ? getCategoryValues($filterModeCategory) : [],
109109
);
110110
111-
// Auto-open dropdown when filter mode activates and scroll to selected section
111+
// Auto-scroll to selected section when filter mode activates
112112
$effect(() => {
113113
if ($isFilterModeActive && $filterModeCategory) {
114-
isOpen = true;
115-
116114
// Scroll to the selected category section after the modal renders
117115
tick().then(() => {
118116
const category = $filterModeCategory;
@@ -139,21 +137,18 @@ $effect(() => {
139137
}
140138
});
141139
142-
// Close modal when filter mode is deactivated
143-
$effect(() => {
144-
if (!$isFilterModeActive && isOpen) {
145-
// Don't auto-close on mode deactivation - let user close manually or via Escape
146-
}
147-
});
148-
149-
// Close modal and clear filter mode
150-
function closeModal() {
151-
isOpen = false;
140+
// Close keyboard filter mode
141+
function closeKeyboardFilterMode() {
152142
isFilterModeActive.set(false);
153143
filterModeCategory.set(null);
154144
filterModePrefix.set(null);
155145
}
156146
147+
// Close regular dropdown
148+
function closeDropdown() {
149+
isOpen = false;
150+
}
151+
157152
// Method to toggle filter by index (called from keyboard shortcuts)
158153
export function toggleFilterByIndex(index: number) {
159154
if (index < 0 || index >= currentCategoryValues.length) return;
@@ -211,13 +206,19 @@ $effect(() => {
211206
});
212207
</script>
213208

214-
<!-- Handle Escape key to close modal -->
209+
<!-- Handle Escape key to close keyboard filter mode or dropdown -->
215210
<svelte:window
216211
onkeydown={(e) => {
217-
if (e.key === 'Escape' && isOpen) {
218-
e.preventDefault();
219-
e.stopPropagation();
220-
closeModal();
212+
if (e.key === 'Escape') {
213+
if ($isFilterModeActive) {
214+
e.preventDefault();
215+
e.stopPropagation();
216+
closeKeyboardFilterMode();
217+
} else if (isOpen) {
218+
e.preventDefault();
219+
e.stopPropagation();
220+
closeDropdown();
221+
}
221222
}
222223
}}
223224
/>
@@ -269,14 +270,14 @@ $effect(() => {
269270
{/if}
270271
</button>
271272

272-
<!-- Modal overlay for keyboard mode -->
273-
{#if isOpen && hasFacets && $isFilterModeActive}
273+
<!-- Modal overlay for keyboard mode (independent of isOpen) -->
274+
{#if hasFacets && $isFilterModeActive && $filterModeCategory}
274275
<!-- svelte-ignore a11y_no_static_element_interactions -->
275276
<!-- svelte-ignore a11y_click_events_have_key_events -->
276277
<!-- svelte-ignore a11y_interactive_supports_focus -->
277278
<div
278279
class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center p-4"
279-
onclick={closeModal}
280+
onclick={closeKeyboardFilterMode}
280281
role="dialog"
281282
aria-modal="true"
282283
aria-label="Filter selection"
@@ -290,7 +291,7 @@ $effect(() => {
290291
<div class="sticky top-0 bg-white border-b border-gray-200 px-4 py-3 flex items-center justify-between">
291292
<h2 class="text-lg font-heading text-forest">Filters</h2>
292293
<button
293-
onclick={closeModal}
294+
onclick={closeKeyboardFilterMode}
294295
class="p-2 text-gray-500 hover:text-gray-700 rounded-lg hover:bg-gray-100"
295296
aria-label="Close"
296297
>
@@ -448,8 +449,10 @@ $effect(() => {
448449
</div>
449450
</div>
450451
</div>
452+
{/if}
453+
451454
<!-- Regular dropdown for non-keyboard mode -->
452-
{:else if isOpen && hasFacets}
455+
{#if isOpen && hasFacets && !$isFilterModeActive}
453456
<div
454457
class="absolute left-0 top-full mt-2 w-72 bg-white rounded-lg shadow-xl border border-gray-200 z-50 p-4 max-h-80 overflow-y-auto"
455458
>

0 commit comments

Comments
 (0)