All files / src/components/SortControl SortControl.tsx

100% Statements 9/9
100% Branches 4/4
100% Functions 4/4
100% Lines 7/7

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                                                                15x 15x 2x   15x 2x     15x                               40x                                                  
import React from 'react';
import Box from '@mui/material/Box';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import { useTranslation } from 'react-i18next';
 
export type SortField = string;
export type SortOrder = 'asc' | 'desc';
 
interface SortControlProps<F extends SortField> {
  /** liste des champs à trier */
  fields: Array<{ value: F; label: React.ReactNode }>;
  /** champ actuellement sélectionné */
  sortBy: F;
  /** ordre actuel */
  order: SortOrder;
  /** callback quand on change soit le champ, soit l’ordre */
  onSortChange: (sortBy: F, order: SortOrder) => void;
  label: String;
}
 
export function SortControl<F extends SortField>({
  fields,
  sortBy,
  order,
  onSortChange,
  label
}: SortControlProps<F>) {
  const { t } = useTranslation();
  const handleField = (_: React.MouseEvent<HTMLElement>, newField: F) => {
    if (newField) onSortChange(newField, order);
  };
  const handleOrder = (_: React.MouseEvent<HTMLElement>, newOrder: SortOrder) => {
    if (newOrder) onSortChange(sortBy, newOrder);
  };
 
  return (
    <FormControl component="fieldset" fullWidth>
      <FormLabel component="legend" sx={{ mb: 1 }}>
        {label}
      </FormLabel>
      <Box sx={{ display: 'flex', gap: 1 }}>
        {/* Groupe Champs (personnalisable) */}
        <ToggleButtonGroup
          value={sortBy}
          exclusive
          size="small"
          onChange={handleField}
          aria-label={t('sorting.title')}
          sx={{ flex: 1 }}
        >
          {fields.map(({ value, label }) => (
            <ToggleButton key={value} value={value} aria-label={String(value)}>
              {label}
            </ToggleButton>
          ))}
        </ToggleButtonGroup>
 
        {/* Groupe Ordre (toujours le même) */}
        <ToggleButtonGroup
          value={order}
          exclusive
          size="small"
          onChange={handleOrder}
          aria-label={t('sorting.order')}
        >
          <ToggleButton value="asc" aria-label={t('sorting.ascendant')}>
            <ArrowUpwardIcon fontSize="small" />
          </ToggleButton>
          <ToggleButton value="desc" aria-label={t('sorting.descendant')}>
            <ArrowDownwardIcon fontSize="small" />
          </ToggleButton>
        </ToggleButtonGroup>
      </Box>
    </FormControl>
  );
}