All files / benchmark/src/components ControlPanel.tsx

100% Statements 10/10
100% Branches 8/8
100% Functions 9/9
100% Lines 10/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108                                                                    66x   66x                 13x           3x     264x                 3x     264x                 3x   264x                     3x                                      
import type { ChangeEvent } from "react";
import type {
  AccountTier,
  FilterState,
  Region,
  SortDirection,
  SortKey
} from "../data";
import { REGIONS, SORT_OPTIONS, TIERS } from "../data";
import type { ThemeMode } from "../usePersistentTheme";
 
export interface ControlPanelProps {
  filters: FilterState;
  appliedQuery?: string;
  theme: ThemeMode;
  onQueryChange: (value: string) => void;
  onRegionChange: (value: Region | "all") => void;
  onTierChange: (value: AccountTier | "all") => void;
  onSortKeyChange: (value: SortKey) => void;
  onSortDirectionChange: (value: SortDirection) => void;
  onThemeToggle: () => void;
}
 
export function ControlPanel({
  filters,
  appliedQuery,
  theme,
  onQueryChange,
  onRegionChange,
  onTierChange,
  onSortKeyChange,
  onSortDirectionChange,
  onThemeToggle
}: ControlPanelProps) {
  const describedBy = appliedQuery === undefined ? undefined : "applied-query";
 
  return (
    <section className="panel controls-panel" aria-label="Dashboard controls">
      <label className="field">
        <span>Search</span>
        <input
          type="search"
          value={filters.query}
          placeholder="Search account, owner, region, tier"
          aria-describedby={describedBy}
          onChange={(event: ChangeEvent<HTMLInputElement>) => onQueryChange(event.target.value)}
        />
      </label>
 
      <label className="field">
        <span>Region</span>
        <select value={filters.region} onChange={(event) => onRegionChange(event.target.value as Region | "all")}>
          <option value="all">All regions</option>
          {REGIONS.map((region) => (
            <option key={region} value={region}>
              {region}
            </option>
          ))}
        </select>
      </label>
 
      <label className="field">
        <span>Tier</span>
        <select value={filters.tier} onChange={(event) => onTierChange(event.target.value as AccountTier | "all")}>
          <option value="all">All tiers</option>
          {TIERS.map((tier) => (
            <option key={tier} value={tier}>
              {tier}
            </option>
          ))}
        </select>
      </label>
 
      <label className="field">
        <span>Sort</span>
        <select value={filters.sortKey} onChange={(event) => onSortKeyChange(event.target.value as SortKey)}>
          {SORT_OPTIONS.map((option) => (
            <option key={option.value} value={option.value}>
              {option.label}
            </option>
          ))}
        </select>
      </label>
 
      <label className="field">
        <span>Order</span>
        <select
          value={filters.sortDirection}
          onChange={(event) => onSortDirectionChange(event.target.value as SortDirection)}
        >
          <option value="desc">Desc</option>
          <option value="asc">Asc</option>
        </select>
      </label>
 
      <button className="toggle-button" type="button" aria-pressed={theme === "dark"} onClick={onThemeToggle}>
        {theme === "dark" ? "Light mode" : "Dark mode"}
      </button>
 
      {appliedQuery === undefined ? null : (
        <span id="applied-query" className="visually-hidden">
          Applied search query: {appliedQuery || "empty"}
        </span>
      )}
    </section>
  );
}