From be267d43d8670bf27bce9ffba794a9bf6858b54d Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Fri, 2 Jan 2026 17:00:34 +0300 Subject: [PATCH] feat(CheckboxFilter): add comprehencive documentation --- .../ui/CheckboxFilter/CheckboxFilter.svelte | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/shared/ui/CheckboxFilter/CheckboxFilter.svelte b/src/shared/ui/CheckboxFilter/CheckboxFilter.svelte index 25a067d..a910019 100644 --- a/src/shared/ui/CheckboxFilter/CheckboxFilter.svelte +++ b/src/shared/ui/CheckboxFilter/CheckboxFilter.svelte @@ -10,17 +10,37 @@ import { onMount } from 'svelte'; import { cubicOut } from 'svelte/easing'; import { slide } from 'svelte/transition'; +/** + * CheckboxFilter Component + * + * A collapsible category filter with checkboxes. Displays selected count as a badge + * and supports reduced motion for accessibility. Used in sidebar filtering UIs. + * + * Design choices: + * - Open by default for immediate visibility and interaction + * - Badge shown only when filters are active to reduce visual noise + * - Transitions use cubicOut for natural deceleration + * - Local transition prevents animation when component first renders + */ + interface CategoryFilterProps { + /** Display name for this filter group (e.g., "Categories", "Tags") */ filterName: string; + /** Array of categories with their selection states */ categories: Category[]; + /** Callback when a category checkbox is toggled */ onCategoryToggle: (id: string) => void; } const { filterName, categories, onCategoryToggle }: CategoryFilterProps = $props(); +// Toggle state - defaults to open for better discoverability let isOpen = $state(true); +// Accessibility preference to disable animations let prefersReducedMotion = $state(false); +// Check reduced motion preference on mount (window access required) +// Event listener allows responding to system preference changes onMount(() => { if (typeof window !== 'undefined') { const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); @@ -35,21 +55,24 @@ onMount(() => { } }); -// Optimized animation configuration +// Animation config respects user preferences - zero duration if reduced motion enabled +// Local modifier prevents animation on initial render, only animates user interactions const slideConfig = $derived({ duration: prefersReducedMotion ? 0 : 250, easing: cubicOut, }); -// Count selected categories for badge +// Derived for reactive updates when categories change - avoids recomputing on every render const selectedCount = $derived(categories.filter(c => c.selected).length); const hasSelection = $derived(selectedCount > 0); + +
0); >

{filterName}

+
+ {#if hasSelection} 0);
+ {#if isOpen}
0); >
+ + {#each categories as category (category.id)}