Skip to content

Commit

Permalink
Add hover color
Browse files Browse the repository at this point in the history
  • Loading branch information
standeren committed Jan 4, 2024
1 parent c3fe32d commit dc14465
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
--border-radius: var(--fds-border_radius-small);
--selected-square-colour: var(--fds-semantic-surface-action-second-default);
--unselected-square-colour: var(--fds-semantic-surface-action-second-no_fill-active);
--hover-square-color: var(--fds-semantic-surface-action-subtle);
--thumb-width: calc(100% / 12);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import React, { ChangeEvent, useEffect, useState } from 'react';
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
import classes from './StudioGridSelector.module.css';
import cn from 'classnames';
import { GridSize } from './types/GridSize';

type OptionData = {
value: GridSize;
positionX: number;
};

type StudioGridSelectorProps = {
disabled?: boolean;
sliderValue?: GridSize;
Expand All @@ -18,23 +23,38 @@ export const StudioGridSelector = ({
sliderValue = 12,
handleSliderChange,
}: StudioGridSelectorProps) => {
const [value, setValue] = useState<number>(sliderValue);
const [hoverValue, setHoverValue] = useState<number>(0);
const [selectedValue, setSelectedValue] = useState<number>(sliderValue);
const gridValues: GridSize[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
useEffect(() => {
setValue(sliderValue);
setSelectedValue(sliderValue);
}, [sliderValue]);

const optionClassName = (gridValue: number) =>
cn(classes.option, gridValue > value ? classes.outside : classes.inside);
cn(classes.option, gridValue > selectedValue ? classes.outside : classes.inside);

const backgroundCss =
'linear-gradient(\n' + generateLinearGradient(selectedValue, hoverValue) + ')';

const backgroundCss = 'linear-gradient(\n' + generateLinearGradient(value) + ')';
const inputRef = useRef(null);

const handleHover = (event) => {
const inputElement = inputRef.current;
const optionPositionsX: OptionData[] = calculateOptionsPositionsX(inputElement);
optionPositionsX.forEach((optionPosX) => {

Check warning on line 44 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L42-L44

Added lines #L42 - L44 were not covered by tests
if (optionPosX.positionX < event.clientX) {
setHoverValue(optionPosX.value + 1);

Check warning on line 46 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L46

Added line #L46 was not covered by tests
}
});
};

return (
<div
className={cn(classes.sliderContainer, disabled && classes.disabled)}
style={{ '--background': backgroundCss } as React.CSSProperties}
>
<input
ref={inputRef}
className={classes.range}
type='range'
min='1'
Expand All @@ -45,8 +65,12 @@ export const StudioGridSelector = ({
onChange={(event: ChangeEvent<HTMLInputElement>) =>
handleSliderChange(convertToGridSize(event.target.value))
}
onInput={(event: ChangeEvent<HTMLInputElement>) => setValue(parseInt(event.target.value))}
onInput={(event: ChangeEvent<HTMLInputElement>) =>
setSelectedValue(parseInt(event.target.value))

Check warning on line 69 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L69

Added line #L69 was not covered by tests
}
disabled={disabled}
onMouseMove={handleHover}
onMouseLeave={() => setHoverValue(0)}

Check warning on line 73 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L73

Added line #L73 was not covered by tests
/>
<datalist id='gridValues'>
{gridValues.map((gridValue) => (
Expand All @@ -62,19 +86,23 @@ export const StudioGridSelector = ({
);
};

const generateLinearGradient = (gridValue: number): string => {
const generateLinearGradient = (gridValue: number, hoverValue: number): string => {
const gradientLines: string[] = ['to right'];
const gap = '2px';
const gap = '1px';
const insideColour = 'var(--selected-square-colour)';
const outsideColour = 'var(--unselected-square-colour)';
const hoverColour = 'var(--hover-square-color)';
const gapColour = 'white';
const totalBgWidth = `(100% + ${gap})`;

const createStep = (option: number) => {
const startSquarePosition = `calc(${totalBgWidth} * ${option - 1} / 12)`;
const endSquarePosition = `calc(${totalBgWidth} * ${option} / 12 - ${gap})`;
const endGapPosition = `calc(${totalBgWidth} * ${option} / 12)`;
const squareColour = option <= gridValue ? insideColour : outsideColour;
let squareColour = option <= gridValue ? insideColour : outsideColour;
if (option < hoverValue && option > gridValue) {
squareColour = hoverColour;

Check warning on line 104 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L104

Added line #L104 was not covered by tests
}
const startSquareLine = `${squareColour} ${startSquarePosition}`;
const endSquareLine = `${squareColour} ${endSquarePosition}`;
const startGapLine = `${gapColour} ${endSquarePosition}`;
Expand All @@ -93,3 +121,20 @@ const convertToGridSize = (value: string): GridSize => {
const int = parseInt(value);
return int as GridSize;
};

const calculateOptionsPositionsX = (inputElement): OptionData[] => {
if (inputElement) {
const datalistElement = inputElement.list;

Check warning on line 127 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L127

Added line #L127 was not covered by tests

if (datalistElement) {
return Array.from(datalistElement.options).map((option: HTMLOptionElement) => {
const optionRect = option.getBoundingClientRect();
const optionData: OptionData = {

Check warning on line 132 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L130-L132

Added lines #L130 - L132 were not covered by tests
value: parseInt(option.value) as GridSize,
positionX: optionRect.x,
};
return optionData;

Check warning on line 136 in frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx

View check run for this annotation

Codecov / codecov/patch

frontend/libs/studio-components/src/components/StudioGridSelector/StudioGridSelector.tsx#L136

Added line #L136 was not covered by tests
});
}
}
};

0 comments on commit dc14465

Please sign in to comment.