All files / src/components/TimelineSlider index.tsx

0% Statements 0/12
0% Branches 0/6
0% Functions 0/4
0% Lines 0/11

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                                                                                                                                                           
import React, { useMemo } from 'react';
 
import { useTheme } from '@mui/material';
 
import TimelineMarker from './TimelineMarker';
import TimelineRail from './TimelineRail';
import './styles.scss';
 
export type TimelineSliderMark = {
  color: string;
  labelBottom?: string;
  labelTop?: string;
  onClick?: () => void;
  size: 'small' | 'medium' | 'large';
  value: number;
};
 
export type TimelineSliderProps = {
  labelEnd?: string;
  labelSelected?: string;
  labelStart?: string;
  marks: TimelineSliderMark[];
};
 
const TimelineSlider = ({ labelEnd, labelSelected, labelStart, marks }: TimelineSliderProps): JSX.Element => {
  const theme = useTheme();
 
  const { minValue, maxValue } = useMemo(() => {
    const values = marks.map((mark) => mark.value);
    if (values.length > 0) {
      return {
        minValue: Math.min(...values),
        maxValue: Math.max(...values),
      };
    } else {
      return {
        minValue: 0,
        maxValue: 1,
      };
    }
  }, [marks]);
 
  const range = maxValue - minValue;
 
  return (
    <div className={'timeline'}>
      <div className={'timeline-label'} style={{ marginRight: theme.spacing(2) }}>
        {labelStart}
      </div>
      <div className='timeline-container'>
        <TimelineRail />
 
        {marks.map((mark, idx) => {
          const normalizedValue = range === 0 ? 1 : (mark.value - minValue) / range;
 
          return (
            <TimelineMarker
              key={idx}
              color={mark.color}
              labelBottom={mark.labelBottom}
              labelTop={mark.labelTop}
              onClick={mark.onClick}
              size={mark.size}
              value={normalizedValue}
            />
          );
        })}
      </div>
      <div className={'timeline-label'} style={{ marginLeft: theme.spacing(2) }}>
        {labelEnd}
      </div>
      {labelSelected && <div className={'timeline-selected-label'}>{labelSelected}</div>}
    </div>
  );
};
 
export default TimelineSlider;