feat(FilterGroup): refactor CheckboxFilter component to FilterGroup
This commit is contained in:
@@ -1,137 +0,0 @@
|
|||||||
<!--
|
|
||||||
Component: CheckboxFilter
|
|
||||||
A collapsible property filter with checkboxes. Displate selected count as a badge
|
|
||||||
and supports reduced motion for accessibility.
|
|
||||||
- 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
|
|
||||||
-->
|
|
||||||
<script lang="ts">
|
|
||||||
import {
|
|
||||||
type Filter,
|
|
||||||
springySlideFade,
|
|
||||||
} from '$shared/lib';
|
|
||||||
import { Badge } from '$shared/shadcn/ui/badge';
|
|
||||||
import { buttonVariants } from '$shared/shadcn/ui/button';
|
|
||||||
import { Checkbox } from '$shared/shadcn/ui/checkbox';
|
|
||||||
import {
|
|
||||||
Root as CollapsibleRoot,
|
|
||||||
Trigger as CollapsibleTrigger,
|
|
||||||
} from '$shared/shadcn/ui/collapsible';
|
|
||||||
import { Label } from '$shared/shadcn/ui/label';
|
|
||||||
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
|
||||||
import { cubicOut } from 'svelte/easing';
|
|
||||||
import { prefersReducedMotion } from 'svelte/motion';
|
|
||||||
|
|
||||||
interface PropertyFilterProps {
|
|
||||||
/** Label for this filter group (e.g., "Properties", "Tags") */
|
|
||||||
displayedLabel: string;
|
|
||||||
/** Filter entity */
|
|
||||||
filter: Filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { displayedLabel, filter }: PropertyFilterProps = $props();
|
|
||||||
|
|
||||||
// Toggle state - defaults to open for better discoverability
|
|
||||||
let isOpen = $state(true);
|
|
||||||
|
|
||||||
// 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.current ? 0 : 150,
|
|
||||||
easing: cubicOut,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Derived for reactive updates when properties change - avoids recomputing on every render
|
|
||||||
const selectedCount = $derived(filter.selectedCount);
|
|
||||||
const hasSelection = $derived(selectedCount > 0);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Collapsible card wrapper with subtle hover state for affordance -->
|
|
||||||
<CollapsibleRoot
|
|
||||||
bind:open={isOpen}
|
|
||||||
class="w-full bg-card transition-colors hover:bg-accent/5"
|
|
||||||
>
|
|
||||||
<!-- Trigger row: title, expand indicator, and optional count badge -->
|
|
||||||
<div class="flex items-center justify-between px-3 sm:px-4 py-2">
|
|
||||||
<CollapsibleTrigger
|
|
||||||
class={buttonVariants({
|
|
||||||
variant: 'ghost',
|
|
||||||
size: 'sm',
|
|
||||||
class: 'flex-1 justify-between gap-2 hover:bg-transparent focus-visible:ring-1 focus-visible:ring-ring',
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<h4 class="text-xs sm:text-sm font-semibold">{displayedLabel}</h4>
|
|
||||||
|
|
||||||
<!-- Badge only appears when items are selected to avoid clutter -->
|
|
||||||
{#if hasSelection}
|
|
||||||
<Badge
|
|
||||||
variant="secondary"
|
|
||||||
data-testid="badge"
|
|
||||||
class="mr-auto h-4 sm:h-5 min-w-4 sm:min-w-5 px-1 sm:px-1.5 text-[10px] sm:text-xs font-medium tabular-nums"
|
|
||||||
>
|
|
||||||
{selectedCount}
|
|
||||||
</Badge>
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<!-- Chevron rotates based on open state for visual feedback -->
|
|
||||||
<div
|
|
||||||
data-testid="chevron"
|
|
||||||
class="shrink-0 transition-transform duration-200 ease-out"
|
|
||||||
style:transform={isOpen ? 'rotate(0deg)' : 'rotate(-90deg)'}
|
|
||||||
>
|
|
||||||
<ChevronDownIcon class="h-3.5 w-3.5 sm:h-4 sm:w-4" />
|
|
||||||
</div>
|
|
||||||
</CollapsibleTrigger>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Expandable content with slide animation -->
|
|
||||||
{#if isOpen}
|
|
||||||
<div
|
|
||||||
transition:springySlideFade|local={slideConfig}
|
|
||||||
class="will-change-[height,opacity]"
|
|
||||||
>
|
|
||||||
<div class="px-4 py-3">
|
|
||||||
<div class="flex flex-col gap-0.5">
|
|
||||||
<!-- Each item: checkbox + label with interactive hover/focus states -->
|
|
||||||
<!-- Keyed by property.id for efficient DOM updates -->
|
|
||||||
{#each filter.properties as property (property.id)}
|
|
||||||
<Label
|
|
||||||
for={property.id}
|
|
||||||
class="
|
|
||||||
group flex items-center gap-3 cursor-pointer rounded-md px-2 py-1.5 -mx-2
|
|
||||||
transition-colors duration-150 ease-out
|
|
||||||
hover:bg-accent/50 focus-within:bg-accent/50
|
|
||||||
active:scale-[0.98] active:transition-transform active:duration-75
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<!-- Checkbox handles toggle, styled for accessibility with focus rings -->
|
|
||||||
<Checkbox
|
|
||||||
id={property.id}
|
|
||||||
bind:checked={property.selected}
|
|
||||||
class="
|
|
||||||
shrink-0 cursor-pointer transition-all duration-150 ease-out
|
|
||||||
data-[state=checked]:scale-100
|
|
||||||
hover:border-primary/50
|
|
||||||
focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<!-- Label text changes weight/color based on selection state -->
|
|
||||||
<span
|
|
||||||
class="
|
|
||||||
text-sm select-none transition-all duration-150 ease-out
|
|
||||||
group-hover:text-foreground
|
|
||||||
text-muted-foreground
|
|
||||||
{property.selected ? 'font-medium text-foreground' : ''}
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{property.name}
|
|
||||||
</span>
|
|
||||||
</Label>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</CollapsibleRoot>
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<script module>
|
<script module>
|
||||||
import { createFilter } from '$shared/lib';
|
import { createFilter } from '$shared/lib';
|
||||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||||
import CheckboxFilter from './CheckboxFilter.svelte';
|
import FilterGroup from './FilterGroup.svelte';
|
||||||
|
|
||||||
const { Story } = defineMeta({
|
const { Story } = defineMeta({
|
||||||
title: 'Shared/CheckboxFilter',
|
title: 'Shared/FilterGroup',
|
||||||
tags: ['autodocs'],
|
tags: ['autodocs'],
|
||||||
parameters: {
|
parameters: {
|
||||||
docs: {
|
docs: {
|
||||||
@@ -66,12 +66,12 @@ const selectedFilter = createFilter({
|
|||||||
|
|
||||||
<Story name="Default">
|
<Story name="Default">
|
||||||
{#snippet template(args)}
|
{#snippet template(args)}
|
||||||
<CheckboxFilter filter={defaultFilter} displayedLabel="Zoo" {...args} />
|
<FilterGroup filter={defaultFilter} displayedLabel="Zoo" {...args} />
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Story>
|
</Story>
|
||||||
|
|
||||||
<Story name="Selected">
|
<Story name="Selected">
|
||||||
{#snippet template(args)}
|
{#snippet template(args)}
|
||||||
<CheckboxFilter filter={selectedFilter} displayedLabel="Shopping list" {...args} />
|
<FilterGroup filter={selectedFilter} displayedLabel="Shopping list" {...args} />
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Story>
|
</Story>
|
||||||
71
src/shared/ui/FilterGroup/FilterGroup.svelte
Normal file
71
src/shared/ui/FilterGroup/FilterGroup.svelte
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<!--
|
||||||
|
Component: FilterGroup
|
||||||
|
Property filter group. Flat list of toggle buttons — no collapsible.
|
||||||
|
-->
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Filter } from '$shared/lib';
|
||||||
|
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||||
|
import { Button } from '$shared/ui';
|
||||||
|
import { Label } from '$shared/ui';
|
||||||
|
import DotIcon from '@lucide/svelte/icons/dot';
|
||||||
|
import { cubicOut } from 'svelte/easing';
|
||||||
|
import { draw } from 'svelte/transition';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
/** Label for this filter group (e.g., "Provider", "Tags") */
|
||||||
|
displayedLabel: string;
|
||||||
|
/** Filter entity */
|
||||||
|
filter: Filter;
|
||||||
|
class?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { displayedLabel, filter, class: className }: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet icon()}
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="lucide lucide-dot-icon lucide-dot size-8 stroke-brand"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
transition:draw={{ duration: 200, easing: cubicOut }}
|
||||||
|
cx="12.1"
|
||||||
|
cy="12.1"
|
||||||
|
r="1"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
<div class={cn('flex flex-col', className)}>
|
||||||
|
<Label
|
||||||
|
variant="default"
|
||||||
|
size="sm"
|
||||||
|
bold
|
||||||
|
class="pl-3 md:pl-4 mb-3 md:mb-4"
|
||||||
|
>
|
||||||
|
{displayedLabel}
|
||||||
|
</Label>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-1">
|
||||||
|
{#each filter.properties as property (property.id)}
|
||||||
|
<Button
|
||||||
|
variant="tertiary"
|
||||||
|
active={property.selected}
|
||||||
|
onclick={() => (property.selected = !property.selected)}
|
||||||
|
class="w-full px-3 md:px-4 py-2.5 md:py-3 justify-between text-left text-sm flex"
|
||||||
|
iconPosition="right"
|
||||||
|
icon={property.selected ? icon : undefined}
|
||||||
|
>
|
||||||
|
<span>{property.name}</span>
|
||||||
|
</Button>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -13,10 +13,10 @@ import {
|
|||||||
expect,
|
expect,
|
||||||
it,
|
it,
|
||||||
} from 'vitest';
|
} from 'vitest';
|
||||||
import CheckboxFilter from './CheckboxFilter.svelte';
|
import FilterGroup from './FilterGroup.svelte';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Suite for CheckboxFilter Component
|
* Test Suite for FilterGroup Component
|
||||||
*
|
*
|
||||||
* This suite tests the actual Svelte component rendering, interactions, and behavior
|
* This suite tests the actual Svelte component rendering, interactions, and behavior
|
||||||
* using a real browser environment (Playwright) via @vitest/browser-playwright.
|
* using a real browser environment (Playwright) via @vitest/browser-playwright.
|
||||||
@@ -29,7 +29,7 @@ import CheckboxFilter from './CheckboxFilter.svelte';
|
|||||||
* not as <input type="checkbox">.
|
* not as <input type="checkbox">.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
describe('CheckboxFilter Component', () => {
|
describe('FilterGroup Component', () => {
|
||||||
/**
|
/**
|
||||||
* Helper function to create a filter for testing
|
* Helper function to create a filter for testing
|
||||||
*/
|
*/
|
||||||
@@ -52,7 +52,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
describe('Rendering', () => {
|
describe('Rendering', () => {
|
||||||
it('displays the label', () => {
|
it('displays the label', () => {
|
||||||
const filter = createTestFilter(createMockProperties(3));
|
const filter = createTestFilter(createMockProperties(3));
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test Label',
|
displayedLabel: 'Test Label',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -63,7 +63,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('renders all properties as checkboxes with labels', () => {
|
it('renders all properties as checkboxes with labels', () => {
|
||||||
const properties = createMockProperties(3);
|
const properties = createMockProperties(3);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -77,7 +77,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('shows selected count badge when items are selected', () => {
|
it('shows selected count badge when items are selected', () => {
|
||||||
const properties = createMockProperties(3, [0, 2]); // Select 2 items
|
const properties = createMockProperties(3, [0, 2]); // Select 2 items
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -88,7 +88,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('hides badge when no items selected', () => {
|
it('hides badge when no items selected', () => {
|
||||||
const properties = createMockProperties(3);
|
const properties = createMockProperties(3);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
const { container } = render(CheckboxFilter, {
|
const { container } = render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -100,7 +100,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
|
|
||||||
it('renders with no properties', () => {
|
it('renders with no properties', () => {
|
||||||
const filter = createTestFilter([]);
|
const filter = createTestFilter([]);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Empty Filter',
|
displayedLabel: 'Empty Filter',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -113,7 +113,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('checkboxes reflect initial selected state', async () => {
|
it('checkboxes reflect initial selected state', async () => {
|
||||||
const properties = createMockProperties(3, [0, 2]);
|
const properties = createMockProperties(3, [0, 2]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -132,7 +132,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('clicking checkbox toggles property.selected state', async () => {
|
it('clicking checkbox toggles property.selected state', async () => {
|
||||||
const properties = createMockProperties(3, [0]);
|
const properties = createMockProperties(3, [0]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -164,7 +164,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('label styling changes based on selection state', async () => {
|
it('label styling changes based on selection state', async () => {
|
||||||
const properties = createMockProperties(2, [0]);
|
const properties = createMockProperties(2, [0]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -192,7 +192,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('multiple checkboxes can be toggled independently', async () => {
|
it('multiple checkboxes can be toggled independently', async () => {
|
||||||
const properties = createMockProperties(3);
|
const properties = createMockProperties(3);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -223,7 +223,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
describe('Collapsible Behavior', () => {
|
describe('Collapsible Behavior', () => {
|
||||||
it('is open by default', () => {
|
it('is open by default', () => {
|
||||||
const filter = createTestFilter(createMockProperties(2));
|
const filter = createTestFilter(createMockProperties(2));
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -235,7 +235,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
|
|
||||||
it('clicking trigger toggles open/close state', async () => {
|
it('clicking trigger toggles open/close state', async () => {
|
||||||
const filter = createTestFilter(createMockProperties(2));
|
const filter = createTestFilter(createMockProperties(2));
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -263,7 +263,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
|
|
||||||
it('chevron icon rotates based on open state', async () => {
|
it('chevron icon rotates based on open state', async () => {
|
||||||
const filter = createTestFilter(createMockProperties(2));
|
const filter = createTestFilter(createMockProperties(2));
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -297,7 +297,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('badge shows correct count based on filter.selectedCount', async () => {
|
it('badge shows correct count based on filter.selectedCount', async () => {
|
||||||
const properties = createMockProperties(5, [0, 2, 4]);
|
const properties = createMockProperties(5, [0, 2, 4]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -318,7 +318,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('badge visibility changes with hasSelection (selectedCount > 0)', async () => {
|
it('badge visibility changes with hasSelection (selectedCount > 0)', async () => {
|
||||||
const properties = createMockProperties(2, [0]);
|
const properties = createMockProperties(2, [0]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -347,7 +347,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('badge shows count correctly when all items are selected', () => {
|
it('badge shows count correctly when all items are selected', () => {
|
||||||
const properties = createMockProperties(5, [0, 1, 2, 3, 4]);
|
const properties = createMockProperties(5, [0, 1, 2, 3, 4]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -359,7 +359,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
describe('Accessibility', () => {
|
describe('Accessibility', () => {
|
||||||
it('provides proper ARIA labels on buttons', () => {
|
it('provides proper ARIA labels on buttons', () => {
|
||||||
const filter = createTestFilter(createMockProperties(2));
|
const filter = createTestFilter(createMockProperties(2));
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test Label',
|
displayedLabel: 'Test Label',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -372,7 +372,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('labels are properly associated with checkboxes', async () => {
|
it('labels are properly associated with checkboxes', async () => {
|
||||||
const properties = createMockProperties(3);
|
const properties = createMockProperties(3);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -391,7 +391,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
|
|
||||||
it('checkboxes have proper role', async () => {
|
it('checkboxes have proper role', async () => {
|
||||||
const filter = createTestFilter(createMockProperties(2));
|
const filter = createTestFilter(createMockProperties(2));
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -406,7 +406,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('labels are clickable and toggle associated checkboxes', async () => {
|
it('labels are clickable and toggle associated checkboxes', async () => {
|
||||||
const properties = createMockProperties(2);
|
const properties = createMockProperties(2);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -447,7 +447,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -466,7 +466,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
{ id: '3', name: '(Special) <Characters>', value: '3', selected: false },
|
{ id: '3', name: '(Special) <Characters>', value: '3', selected: false },
|
||||||
];
|
];
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -481,7 +481,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
{ id: '1', name: 'Only One', value: '1', selected: true },
|
{ id: '1', name: 'Only One', value: '1', selected: true },
|
||||||
];
|
];
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Single',
|
displayedLabel: 'Single',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -493,7 +493,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('handles very large number of properties', async () => {
|
it('handles very large number of properties', async () => {
|
||||||
const properties = createMockProperties(50, [0, 25, 49]);
|
const properties = createMockProperties(50, [0, 25, 49]);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Large List',
|
displayedLabel: 'Large List',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -506,7 +506,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
it('updates badge when filter is manipulated externally', async () => {
|
it('updates badge when filter is manipulated externally', async () => {
|
||||||
const properties = createMockProperties(3);
|
const properties = createMockProperties(3);
|
||||||
const filter = createTestFilter(properties);
|
const filter = createTestFilter(properties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Test',
|
displayedLabel: 'Test',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
@@ -537,7 +537,7 @@ describe('CheckboxFilter Component', () => {
|
|||||||
{ id: 'monospace', name: 'Monospace', value: 'monospace', selected: false },
|
{ id: 'monospace', name: 'Monospace', value: 'monospace', selected: false },
|
||||||
];
|
];
|
||||||
const filter = createTestFilter(realProperties);
|
const filter = createTestFilter(realProperties);
|
||||||
render(CheckboxFilter, {
|
render(FilterGroup, {
|
||||||
displayedLabel: 'Font Category',
|
displayedLabel: 'Font Category',
|
||||||
filter,
|
filter,
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user