refactor(finder): build filters from the shared button

The log panel already presents filters as a "Filter by" label followed by
a row of buttons which carry their state in the primary variant. The
finder had grown its own markup and styles for the same idea, so it now
uses the same component and the bespoke styles go.

Unlike the log the accessible name stays the field label rather than
changing with the state, since aria-pressed already carries that and a
name which moves is harder to target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DzALEq9gGWwFmwTdgAiFcY
This commit is contained in:
Claude
2026-08-19 04:23:23 +00:00
parent 90ae00c88e
commit 4fa24ae9bd
2 changed files with 15 additions and 38 deletions
@@ -48,32 +48,6 @@
margin-right: 0.15rem; margin-right: 0.15rem;
} }
.filterBadge {
font-size: calc(1rem - 3px);
line-height: 1;
color: $ui-white;
background-color: $gray-1000;
border: 1px solid $gray-900;
border-radius: 3px;
padding: 0.3rem 0.5rem;
cursor: pointer;
&:hover {
background-color: $gray-900;
}
&:focus-visible {
outline: 2px solid $blue-700;
outline-offset: 1px;
}
&[data-active='true'] {
background-color: $blue-700;
border-color: $blue-700;
color: $ui-white;
}
}
.data { .data {
display: grid; display: grid;
grid-template-areas: grid-template-areas:
+15 -12
View File
@@ -1,6 +1,7 @@
import { EntryId, MaybeString } from 'ontime-types'; import { EntryId, MaybeString } from 'ontime-types';
import { KeyboardEvent, PointerEvent, useDeferredValue, useEffect, useRef, useState } from 'react'; import { KeyboardEvent, PointerEvent, useDeferredValue, useEffect, useRef, useState } from 'react';
import Button from '../../../common/components/buttons/Button';
import Input from '../../../common/components/input/input/Input'; import Input from '../../../common/components/input/input/Input';
import Kbd from '../../../common/components/kbd/Kbd'; import Kbd from '../../../common/components/kbd/Kbd';
import Modal from '../../../common/components/modal/Modal'; import Modal from '../../../common/components/modal/Modal';
@@ -115,18 +116,20 @@ export default function Finder({ isOpen, onClose }: FinderProps) {
/> />
<div className={style.filters} data-testid='finder-filters'> <div className={style.filters} data-testid='finder-filters'>
<span className={style.filterLabel}>Filter by</span> <span className={style.filterLabel}>Filter by</span>
{filters.map((option) => ( {filters.map((option) => {
<button const isActive = appliedFilter === option.key;
key={option.key} return (
type='button' <Button
className={style.filterBadge} key={option.key}
data-active={appliedFilter === option.key} variant={isActive ? 'primary' : 'subtle'}
aria-pressed={appliedFilter === option.key} size='small'
onClick={() => handleFilter(option.key)} aria-pressed={isActive}
> onClick={() => handleFilter(option.key)}
{option.label} >
</button> {option.label}
))} </Button>
);
})}
</div> </div>
<ul className={style.scrollContainer}> <ul className={style.scrollContainer}>
{error && <li className={style.error}>{error}</li>} {error && <li className={style.error}>{error}</li>}