Skip to content

Commit

Permalink
Percentage slider -> Aligned min/max dividers (#427)
Browse files Browse the repository at this point in the history
* Percentage slider -> Aligned min/max dividers

* Added a prop to conditionally handle alignment of the end numbers of the percentage slider

* Feedback changes have been implemented

* Last value misalignment fixed for Slider Input component

* Update mark logic to allow center at the extremities

* Update wording in slider input example

* Update padding in Title percentage when marks are centered

---------

Co-authored-by: Isabel Anguiano <[email protected]>
  • Loading branch information
fti-rchaniya and isacoder authored Dec 19, 2023
1 parent 246075d commit 82e9177
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
14 changes: 8 additions & 6 deletions src/Form/atoms/SliderInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const Mark = styled.span<{leftValue: number}>`
background-color: hsl(205, 77%, 64%);
`;

const MarkLabel = styled.span<{leftValue: number, alignment?: IMartAlignment,}>`
const MarkLabel = styled.span<{leftValue: number, alignment?: IMarkAlignment}>`
position: absolute;
top: -24px;
left: ${({leftValue}) => `calc(${leftValue}% + 7px)`};
Expand Down Expand Up @@ -161,7 +161,7 @@ const valueToPercent = (value: number, min: number, max: number) : number => {
// };


const getMarkAlignment = (value: number, min: number, max: number) : IMartAlignment => {
const getMarkAlignment = (value: number, min: number, max: number) : IMarkAlignment => {
if(value === min) {
return 'right';
}
Expand All @@ -173,7 +173,7 @@ const getMarkAlignment = (value: number, min: number, max: number) : IMartAlignm
return 'center';
};

const renderMarks = (markList: ISliderMark[], min: number, max: number, listTag: string) => {
const renderMarks = (markList: ISliderMark[], min: number, max: number, listTag: string, allMarkCentered?: boolean) => {

const listOptions : JSX.Element[] = [];
const marksElements = markList.map(({value, label}, index) => {
Expand All @@ -189,7 +189,7 @@ const renderMarks = (markList: ISliderMark[], min: number, max: number, listTag:
/>
<MarkLabel
leftValue={left}
alignment={getMarkAlignment(value, min, max)}
alignment={allMarkCentered ? 'center' : getMarkAlignment(value, min, max)}
>
{label}
</MarkLabel>
Expand All @@ -208,7 +208,7 @@ const renderMarks = (markList: ISliderMark[], min: number, max: number, listTag:

};

export type IMartAlignment = 'left' | 'center' | 'right';
export type IMarkAlignment = 'left' | 'center' | 'right';

export interface ISliderMark {
value: number
Expand All @@ -227,6 +227,7 @@ interface ISliderOwnProps {
showValue?: boolean
inputCallback?: (value: number) => void
onChangeCallback?: (value: number) => void
allMarkCentered?: boolean
}

export type ISlider = ISliderOwnProps & InputHTMLAttributes<HTMLInputElement>;
Expand All @@ -243,6 +244,7 @@ const SliderInput : React.FC<ISlider> = ({
onlyMarkSelect = false,
inputCallback = () => {},
onChangeCallback = () => {},
allMarkCentered = false,
...props
}) => {

Expand Down Expand Up @@ -316,7 +318,7 @@ const SliderInput : React.FC<ISlider> = ({
<SliderWrapper disabled={disabled}>
<Rail />
<ThumbWrapper>
{marks && renderMarks(marks, minValid, maxValid, `sliderList-${minValid}-${maxValid}`)}
{marks && renderMarks(marks, minValid, maxValid, `sliderList-${minValid}-${maxValid}`, allMarkCentered)}
{isGhostActive && onlyMarkSelect
? (
<GhostThumb
Expand Down
13 changes: 10 additions & 3 deletions src/Form/molecules/PercentageSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import Label from '../atoms/Label';


const Container = styled.div``;
const Headers = styled.div`
const Headers = styled.div<{allMarkCentered?:boolean}>`
font-size: 14px;
color: hsl(207, 5%, 57%);
display: flex;
justify-content: space-between;
margin-bottom: 20px;
padding: 0 6px;
${({allMarkCentered}) => allMarkCentered ?
`padding: 0;`
:
`padding: 0 6px;`
};
`;

const ValueTitle = styled(Label)`
Expand Down Expand Up @@ -53,6 +57,7 @@ interface IPercentageSliderProps {
inputCallback?: (value: number) => void
updateThumbColor?: (value: number) => IFeedbackColor
updateTitle?: (value: number) => string
allMarkCentered?: boolean
}

type IPercentageSlider = IPercentageSliderProps & InputHTMLAttributes<HTMLInputElement>;
Expand All @@ -65,6 +70,7 @@ const PercentageSlider: React.FC<IPercentageSlider> = (
updateThumbColor,
updateTitle,
showValue,
allMarkCentered,
...props
}
) => {
Expand All @@ -79,7 +85,7 @@ const PercentageSlider: React.FC<IPercentageSlider> = (

return(
<Container>
<Headers>
<Headers allMarkCentered={allMarkCentered}>
<Label
htmlFor='percentage-slider'
labelText={updateTitle ? updateTitle(selectedValue) : getTitleLevel(selectedValue)}
Expand All @@ -99,6 +105,7 @@ const PercentageSlider: React.FC<IPercentageSlider> = (
? updateThumbColor(selectedValue)
: getThumbColor(selectedValue)
}
allMarkCentered={allMarkCentered}
/>
</Container>
);
Expand Down
12 changes: 7 additions & 5 deletions storybook/src/stories/Form/Input/PercentageSlider.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const exampleMarks : ISliderMark[] = [
label:'100%',
},
];

export const _PercentageSlider = () => {
const title = text('Title', 'Duration');
const disabled = boolean('Disabled', false);
Expand All @@ -49,6 +49,7 @@ export const _PercentageSlider = () => {
const showValue = action('Input Callback');
const marks = object('Marks', exampleMarks);
const showTitle = boolean("Show Value", true);
const allMarkCentered = boolean('Center all mark values', false);

// const step = number('Step', 1); // still fixing step option
const handleUpdate = (value: number) => {
Expand All @@ -60,23 +61,23 @@ export const _PercentageSlider = () => {
if(value <= 20) {
return 'neutral';
}

if((value > 20) && (value <= 80)) {
return 'info';
}

return 'error';
}

const otherTitlesHandler = (value: number) : string => {
if(value <= 20) {
return 'Small sound';
}

if((value > 20) && (value <= 80)) {
return 'Normal sound';
}

return 'Dangerous sound';
}

Expand All @@ -92,6 +93,7 @@ export const _PercentageSlider = () => {
updateThumbColor={customThumb ? otherColorHandler : undefined }
updateTitle={customTitle ? otherTitlesHandler : undefined}
showValue={showTitle}
allMarkCentered={allMarkCentered}
/>
</Container>
)
Expand Down
4 changes: 3 additions & 1 deletion storybook/src/stories/Form/Input/SliderInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const exampleMarks : ISliderMark[] = [
label:'8H',
},
];


export const _SliderInput = () => {
const disabled = boolean('Disabled', false);
Expand All @@ -60,6 +60,7 @@ export const _SliderInput = () => {
const defaultValue = number('Default value', 6)
const showValue = action('Input Callback');
const marks = object('Marks', exampleMarks);
const allMarkCentered = boolean('Center aligned end numbers', false);
// const step = number('Step', 1); // still fixing step option

const handleUpdate = (value: number) => {
Expand All @@ -77,6 +78,7 @@ export const _SliderInput = () => {
inputCallback={handleUpdate}
marks={marks}
defaultValue={defaultValue}
allMarkCentered={allMarkCentered}
/>
</Container>
)
Expand Down

0 comments on commit 82e9177

Please sign in to comment.