Skip to content

Commit

Permalink
perf: use icons instead of SVGs in TimeSlider (#6982)
Browse files Browse the repository at this point in the history
  • Loading branch information
VIKTORVAV99 authored Aug 8, 2024
1 parent d76b2b4 commit c8dce3e
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 63 deletions.
1 change: 0 additions & 1 deletion web/public/images/slider-thumb-day.svg

This file was deleted.

1 change: 0 additions & 1 deletion web/public/images/slider-thumb-night.svg

This file was deleted.

4 changes: 0 additions & 4 deletions web/public/images/slider-thumb.svg

This file was deleted.

42 changes: 0 additions & 42 deletions web/src/components/TimeSlider.test.ts

This file was deleted.

62 changes: 62 additions & 0 deletions web/src/components/TimeSlider.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { render } from '@testing-library/react';
import { ChevronsLeftRight, Moon, Sun } from 'lucide-react';
import { describe, expect, it } from 'vitest';

import { COLORS, getThumbIcon, getTrackBackground } from './TimeSlider';

describe('getTrackBackground', () => {
it('returns the day color when no sets are provided', () => {
expect(getTrackBackground(false, 10)).to.eq(COLORS.LIGHT_DAY);
expect(getTrackBackground(true, 10)).to.eq(COLORS.DARK_DAY);
});

it('returns a linear gradient with night time sets when sets are provided', () => {
const sets = [
[2, 5],
[8, 10],
];
expect(getTrackBackground(false, 10, sets)).toMatchInlineSnapshot(`
"linear-gradient(
90deg,
rgb(243,244,246) 20%, rgb(209,213,219) 20%, rgb(209,213,219) 50%, rgb(243,244,246) 50%,
rgb(243,244,246) 80%, rgb(209,213,219) 80%, rgb(209,213,219) 100%, rgb(243,244,246) 100%
)"
`);
});
});

describe('getThumbIcon', () => {
it('returns "<ChevronsLeftRight size={20} />" when no index or sets are provided', () => {
const { container: expected } = render(
<ChevronsLeftRight size={20} pointerEvents="none" />
);
const { container } = render(getThumbIcon());
expect(container.innerHTML).toEqual(expected.innerHTML);
});

it.each([[10], [35]])(
'returns "<Moon size={16} />" when the index %i is within a night time set',
(index) => {
const sets = [
[7, 21],
[30, 40],
];
const { container: expected } = render(<Moon size={20} pointerEvents="none" />);
const { container } = render(getThumbIcon(index, sets));
expect(container.innerHTML).toEqual(expected.innerHTML);
}
);

it.each([[5], [25], [50]])(
'returns "<Sun size={20} />" when the index %i is not within a night time set',
(index) => {
const sets = [
[7, 21],
[30, 40],
];
const { container: expected } = render(<Sun size={20} pointerEvents="none" />);
const { container } = render(getThumbIcon(index, sets));
expect(container.innerHTML).toEqual(expected.innerHTML);
}
);
});
31 changes: 16 additions & 15 deletions web/src/components/TimeSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ import { scaleLinear } from 'd3-scale';
import { useNightTimes } from 'hooks/nightTimes';
import { useDarkMode } from 'hooks/theme';
import { useAtom, useAtomValue } from 'jotai';
import { ChevronsLeftRight, Moon, Sun } from 'lucide-react';
import { ReactElement } from 'react';
import trackEvent from 'utils/analytics';
import { TimeAverages } from 'utils/constants';
import { useGetZoneFromPath } from 'utils/helpers';
import { isHourlyAtom, timeAverageAtom } from 'utils/state/atoms';

type NightTimeSet = number[];
type ThumbIconPath =
| 'slider-thumb.svg'
| 'slider-thumb-day.svg'
| 'slider-thumb-night.svg';

export interface TimeSliderProps {
onChange: (datetimeIndex: number) => void;
Expand Down Expand Up @@ -60,14 +58,19 @@ export const getTrackBackground = (
export const getThumbIcon = (
selectedIndex?: number,
sets?: NightTimeSet[]
): ThumbIconPath => {
): ReactElement => {
const size = 20;
if (selectedIndex === undefined || !sets || sets.length === 0) {
return 'slider-thumb.svg';
return <ChevronsLeftRight size={size} pointerEvents="none" />;
}
const isValueAtNight = sets.some(
([start, end]) => selectedIndex >= start && selectedIndex <= end && start !== end
);
return isValueAtNight ? 'slider-thumb-night.svg' : 'slider-thumb-day.svg';
return isValueAtNight ? (
<Moon size={size} pointerEvents="none" />
) : (
<Sun size={size} pointerEvents="none" />
);
};

function trackTimeSliderEvent(selectedIndex: number, timeAverage: TimeAverages) {
Expand All @@ -78,7 +81,7 @@ function trackTimeSliderEvent(selectedIndex: number, timeAverage: TimeAverages)

export type TimeSliderBasicProps = TimeSliderProps & {
trackBackground: string;
thumbIcon: ThumbIconPath;
thumbIcon: ReactElement;
};
export function TimeSliderBasic({
onChange,
Expand Down Expand Up @@ -109,13 +112,11 @@ export function TimeSliderBasic({
</SliderPrimitive.Track>
<SliderPrimitive.Thumb
data-test-id="time-slider-input"
className={`block h-6 w-6 rounded-full bg-white bg-center
bg-no-repeat shadow-3xl transition-shadow hover:ring
hover:ring-brand-green/10 hover:ring-opacity-75 focus:outline-none focus-visible:ring
focus-visible:ring-brand-green/10 focus-visible:ring-opacity-75
dark:bg-gray-400 hover:dark:ring-white/70 dark:focus-visible:ring-white/70`}
style={{ backgroundImage: `url(/images/${thumbIcon})` }}
></SliderPrimitive.Thumb>
className="flex h-7 w-7 items-center justify-center rounded-full bg-white outline
outline-1 outline-neutral-200 hover:outline-2 focus-visible:outline-2 dark:bg-gray-900 dark:outline-gray-700"
>
{thumbIcon}
</SliderPrimitive.Thumb>
</SliderPrimitive.Root>
);
}
Expand Down

0 comments on commit c8dce3e

Please sign in to comment.