refactor(idaa): compact filter bar — sr-only labels, +/- stepper for max results

- Group labels (Location, Type, Sort, Max) moved to sr-only — visually hidden,
  accessible to screen readers. Chips are self-descriptive without them.
- Max results chips replaced with a [−] 150 [+] stepper that steps through
  predefined values [25, 50, 100, 150] (+ 200/500 for trusted_access). Minus/plus
  buttons disable at the ends of the list. limit_steps and limit_idx computed as
  $derived in script so onclick closures have access without @const gymnastics.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-05-18 17:18:59 -04:00
parent bb84117991
commit 6857f1226c

View File

@@ -37,6 +37,14 @@ import Help_tech from '$lib/app_components/e_app_help_tech.svelte';
let ae_promises: key_val = $state({});
// Predefined limit steps for the +/- stepper. Trusted staff get larger options
// since they often query with disabled/hidden meetings included.
let limit_steps = $derived($ae_loc.trusted_access ? [25, 50, 100, 150, 200, 500] : [25, 50, 100, 150]);
let limit_idx = $derived.by(() => {
const idx = limit_steps.indexOf($idaa_loc.recovery_meetings.qry__limit);
return idx >= 0 ? idx : limit_steps.length - 1;
});
// *** Functions and Logic
/**
* Reactive Search Trigger
@@ -184,7 +192,7 @@ function set_sort_mode(mode: string) {
<!-- Location: independent toggles (a meeting can be both virtual and in-person) -->
<div class="flex flex-row flex-wrap items-center gap-1">
<span class="text-xs opacity-50">Location:</span>
<span class="sr-only">Location:</span>
<button
type="button"
onclick={() => { $idaa_loc.recovery_meetings.qry__virtual = !$idaa_loc.recovery_meetings.qry__virtual; }}
@@ -211,7 +219,7 @@ function set_sort_mode(mode: string) {
<!-- Type: mutually exclusive; clicking the active chip deselects (goes back to All) -->
<div class="flex flex-row flex-wrap items-center gap-1">
<span class="text-xs opacity-50">Type:</span>
<span class="sr-only">Type:</span>
{#each [
['', 'All', 'Show all meeting types'],
['IDAA', 'IDAA', 'Open to IDAA members only'],
@@ -253,12 +261,12 @@ function set_sort_mode(mode: string) {
<div
class="ae_group ae_row flex w-full max-w-full flex-row flex-wrap items-center justify-center gap-2 p-1">
<!-- Sort + Limit chips -->
<!-- Sort chips + Max results stepper -->
<span class="flex flex-row flex-wrap items-center justify-center gap-x-4 gap-y-1">
<!-- Sort: mutually exclusive chips -->
<div class="flex flex-row flex-wrap items-center gap-1">
<span class="text-xs opacity-50">Sort:</span>
<span class="sr-only">Sort:</span>
{#each [
['updated_on', 'Last Updated', 'fa-clock'],
['name_asc', 'Name AZ', 'fa-sort-alpha-down'],
@@ -279,39 +287,32 @@ function set_sort_mode(mode: string) {
{/each}
</div>
<!-- Limit: mutually exclusive chips; 200/500 for trusted staff only -->
<div class="flex flex-row flex-wrap items-center gap-1">
<span class="text-xs opacity-50">Max:</span>
{#each [25, 50, 100, 150] as n}
{@const active = $idaa_loc.recovery_meetings.qry__limit === n}
<button
type="button"
onclick={() => { $idaa_loc.recovery_meetings.qry__limit = n; }}
aria-pressed={active}
title="Show up to {n} results"
class="novi_btn btn btn-sm transition-all
{active
? 'preset-filled-tertiary-400-600'
: 'preset-outlined-surface-300-700 opacity-60 hover:opacity-100'}">
{n}
</button>
{/each}
{#if $ae_loc.trusted_access}
{#each [200, 500] as n}
{@const active = $idaa_loc.recovery_meetings.qry__limit === n}
<button
type="button"
onclick={() => { $idaa_loc.recovery_meetings.qry__limit = n; }}
aria-pressed={active}
title="Show up to {n} results"
class="novi_btn btn btn-sm transition-all
{active
? 'preset-filled-tertiary-400-600'
: 'preset-outlined-surface-300-700 opacity-60 hover:opacity-100'}">
{n}
</button>
{/each}
{/if}
<!-- Max results: +/- stepper through predefined steps -->
<div class="flex flex-row items-center gap-1">
<span class="sr-only">Max results:</span>
<button
type="button"
onclick={() => { if (limit_idx > 0) $idaa_loc.recovery_meetings.qry__limit = limit_steps[limit_idx - 1]; }}
disabled={limit_idx <= 0}
title="Show fewer results"
class="novi_btn btn btn-sm preset-outlined-surface-300-700 transition-all
{limit_idx <= 0 ? 'opacity-30 cursor-not-allowed' : 'opacity-60 hover:opacity-100'}">
<span class="fas fa-minus"></span>
</button>
<span
class="min-w-10 text-center text-sm font-semibold tabular-nums"
title="Max results shown">
{$idaa_loc.recovery_meetings.qry__limit}
</span>
<button
type="button"
onclick={() => { if (limit_idx < limit_steps.length - 1) $idaa_loc.recovery_meetings.qry__limit = limit_steps[limit_idx + 1]; }}
disabled={limit_idx >= limit_steps.length - 1}
title="Show more results"
class="novi_btn btn btn-sm preset-outlined-surface-300-700 transition-all
{limit_idx >= limit_steps.length - 1 ? 'opacity-30 cursor-not-allowed' : 'opacity-60 hover:opacity-100'}">
<span class="fas fa-plus"></span>
</button>
</div>
</span>