From d4a4803bf4d36d161a79612321428aad0fc2f359 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Mon, 22 Aug 2022 12:41:23 +0200 Subject: [PATCH 01/19] removing Material from slider --- lib/src/slider/Slider.tsx | 253 +++++++++++++++++--------------------- 1 file changed, 116 insertions(+), 137 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 2dc398260..e932e08e4 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -1,6 +1,5 @@ // @ts-nocheck import React, { useState, useMemo, useContext } from "react"; -import Slider from "@material-ui/lab/Slider"; import styled, { ThemeProvider } from "styled-components"; import DxcTextInput from "../text-input/TextInput"; import { spaces } from "../common/variables.js"; @@ -30,6 +29,7 @@ const DxcSlider = ({ size = "fillParent", }: SliderPropsType): JSX.Element => { const [innerValue, setInnerValue] = useState(defaultValue ?? 0); + const [dragging, setDragging] = useState(false); const colorsTheme = useTheme(); const backgroundType = useContext(BackgroundColorContext); @@ -39,19 +39,39 @@ const DxcSlider = ({ () => (labelFormatCallback ? labelFormatCallback(minValue) : minValue), [labelFormatCallback, minValue] ); + const maxLabel = useMemo( () => (labelFormatCallback ? labelFormatCallback(maxValue) : maxValue), [labelFormatCallback, maxValue] ); - const handlerSliderChange = (event, newValue) => { - const valueToCheck = value ?? innerValue; - valueToCheck !== newValue && setInnerValue(newValue); - onChange?.(newValue); + const tickMarks = useMemo(() => { + const ticks = []; + const numberOfMarks = Math.floor(maxValue / step - minValue / step); + let index = 0; + const range = maxValue - minValue; + while (index <= numberOfMarks) { + ticks.push(); + index++; + } + return ticks; + }, [minValue, maxValue, step]); + + const handleSliderChange = (event, newValue) => { + const valueToCheck = event.target.value; + (valueToCheck !== value || valueToCheck !== innerValue) && setInnerValue(valueToCheck); + onChange?.(valueToCheck); }; - const handleSliderOnChangeCommited = (event, selectedValue) => { - onDragEnd?.(selectedValue); + const handleSliderDragging = (event) => { + setDragging(true); + }; + + const handleSliderOnChangeCommited = (event) => { + if (dragging) { + setDragging(false); + onDragEnd?.(event.target.value); + } }; const handlerInputChange = (event) => { @@ -79,17 +99,26 @@ const DxcSlider = ({ {minLabel} )} - = 0 && value) || innerValue} - min={minValue} - max={maxValue} - onChange={handlerSliderChange} - onChangeCommitted={handleSliderOnChangeCommited} - step={step} - marks={marks || []} - disabled={disabled} - aria-labelledby={labelId} - /> + + = 0 && value) || innerValue} + min={minValue} + max={maxValue} + step={step} + marks={marks || []} + disabled={disabled} + aria-labelledby={labelId} + aria-orientation="horizontal" + aria-valuemax={maxValue} + aria-valuemin={minValue} + aria-valuenow={(value != null && value >= 0 && value) || innerValue} + onChange={handleSliderChange} + onMouseUp={handleSliderOnChangeCommited} + onMouseDown={handleSliderDragging} + /> + {marks && {tickMarks}} + {showLimitsValues && ( {maxLabel} @@ -171,136 +200,59 @@ const HelperText = styled.span` line-height: ${(props) => props.theme.helperTextLineHeight}; `; -const SliderContainer = styled.div` - display: flex; - height: 48px; - align-items: center; - - .MuiSlider-root { - min-width: 15rem; - } - .MuiSlider-container { - padding: 30px 24px; - } - .MuiSlider-root.Mui-disabled { - color: ${(props) => - props.backgroundType === "dark" - ? props.theme.disabledThumbBackgroundColorOnDark - : props.theme.disabledThumbBackgroundColor}; - cursor: not-allowed; - } - .Mui-disabled { - & .MuiSlider-thumb { - height: ${(props) => props.theme.thumbHeight}; - width: ${(props) => props.theme.thumbWidth}; - background-color: ${(props) => - props.backgroundType === "dark" - ? props.theme.disabledThumbBackgroundColorOnDark - : props.theme.disabledThumbBackgroundColor}; - top: ${(props) => props.theme.disabledThumbVerticalPosition}; - } - & .MuiSlider-track { - background-color: ${(props) => - props.backgroundType === "dark" - ? props.theme.disabledTrackLineColorOnDark - : props.theme.disabledTrackLineColor}; - } - & .MuiSlider-rail { - background-color: ${(props) => - props.backgroundType === "dark" - ? props.theme.disabledTotalLineColorOnDark - : props.theme.disabledTotalLineColor}; - } - & > .MuiSlider-mark.MuiSlider-markActive { - background-color: ${(props) => - props.backgroundType === "dark" - ? props.theme.disabledTickBackgroundColorOnDark - : props.theme.disabledTickBackgroundColor} !important; - } - & > .MuiSlider-mark { - background-color: ${(props) => - props.backgroundType === "dark" - ? props.theme.disabledTickBackgroundColorOnDark - : props.theme.disabledTickBackgroundColor}; - height: ${(props) => props.theme.tickHeight}; - width: ${(props) => props.theme.tickWidth}; - border-radius: 18px; - top: ${(props) => props.theme.disabledTickVerticalPosition}; - } +const Slider = styled.input` + width: 99%; + height: ${(props) => props.theme.trackLineThickness}; + display: inline-block; + vertical-align: middle; + -webkit-appearance: none; + background-color: ${(props) => + props.backgroundType === "dark" ? props.theme.totalLineColorOnDark : props.theme.totalLineColor}; + background-image: ${(props) => + props.backgroundType === "dark" + ? `linear-gradient(${props.theme.trackLineColorOnDark}, ${props.theme.trackLineColorOnDark})` + : `linear-gradient(${props.theme.trackLineColor}, ${props.theme.trackLineColor})`}; + background-repeat: no-repeat; + background-size: ${(props) => ((props.value - props.min) * 100) / (props.max - props.min) + "% 100%"}; + border-radius: 5px; + &::-webkit-slider-runnable-track { + -webkit-appearance: none; + z-index: 1; + box-shadow: none; + border: none; + background: transparent; + margin: 0px -6px; } - .MuiSlider-thumb { + &::-webkit-slider-thumb { + -webkit-appearance: none; + z-index: 1; height: ${(props) => props.theme.thumbHeight}; width: ${(props) => props.theme.thumbWidth}; - background-color: ${(props) => + border-radius: 25px; + background: ${(props) => props.backgroundType === "dark" ? props.theme.thumbBackgroundColorOnDark : props.theme.thumbBackgroundColor}; - top: ${(props) => props.theme.thumbVerticalPosition}; - border-radius: 9999px; - - :hover, - &.Mui-focusVisible { - box-shadow: none; - } - &.MuiSlider-active { - box-shadow: none; - } - :focus { - outline: ${(props) => (props.backgroundType === "dark" ? props.theme.focusColorOnDark : props.theme.focusColor)} - auto 1px; - outline-offset: 2px; - background-color: ${(props) => + cursor: pointer; + &:active { + background: ${(props) => props.backgroundType === "dark" - ? props.theme.focusThumbBackgroundColorOnDark - : props.theme.focusThumbBackgroundColor}; + ? props.theme.activeThumbBackgroundColor + : props.theme.activeThumbBackgroundColorOnDark}; } - :hover { - background-color: ${(props) => - props.backgroundType === "dark" - ? props.theme.hoverThumbBackgroundColorOnDark - : props.theme.hoverThumbBackgroundColor}; - transform: scale(${(props) => props.theme.hoverThumbScale}); - transform-origin: center; + &:hover { height: ${(props) => props.theme.hoverThumbHeight}; width: ${(props) => props.theme.hoverThumbWidth}; - top: ${(props) => props.theme.hoverThumbVerticalPosition}; - } - :active { - background-color: ${(props) => + background: ${(props) => props.backgroundType === "dark" - ? props.theme.activeThumbBackgroundColorOnDark - : props.theme.activeThumbBackgroundColor}; - transform: scale(${(props) => props.theme.activeThumbScale}); - transform-origin: center; + ? props.theme.hoverThumbBackgroundColor + : props.theme.hoverThumbBackgroundColorOnDark}; } } - .MuiSlider-track { - background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.trackLineColorOnDark : props.theme.trackLineColor}; - height: ${(props) => props.theme.trackLineThickness}; - top: ${(props) => props.theme.trackLineVerticalPosition}; - border-radius: 9999px; - } - .MuiSlider-track.MuiSlider-trackAfter { - background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.trackLineColorOnDark : props.theme.trackLineColor}; - } - .MuiSlider-rail { - background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.totalLineColorOnDark : props.theme.totalLineColor}; - height: ${(props) => props.theme.totalLineThickness}; - top: ${(props) => props.theme.totalLineVerticalPosition}; - } - .MuiSlider-mark.MuiSlider-markActive { - background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.tickBackgroundColorOnDark : props.theme.tickBackgroundColor}; - } - .MuiSlider-mark { - background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.tickBackgroundColorOnDark : props.theme.tickBackgroundColor}; - height: ${(props) => props.theme.tickHeight}; - width: ${(props) => props.theme.tickWidth}; - border-radius: 18px; - top: ${(props) => props.theme.tickVerticalPosition}; - } +`; + +const SliderContainer = styled.div` + display: flex; + height: 48px; + align-items: center; `; const MinLabelContainer = styled.span` @@ -337,6 +289,33 @@ const MaxLabelContainer = styled.span` margin-left: ${(props) => (props.step === 1 ? props.theme.ceilLabelMarginLeft : "1.25rem")}; `; +const SliderInputContainer = styled.div` + position: relative; + width: 100%; + display: flex; + align-items: center; + justify-content: center; +`; + +const MarksContainer = styled.div` + position: absolute; + margin-right: 4px; + width: 99%; + top: 1px; + pointer-events: none; + height: 2px; +`; + +const TickMark = styled.span<{ stepPosition: number }>` + position: absolute; + background: ${(props) => + props.backgroundType === "dark" ? props.theme.tickBackgroundColorOnDark : props.theme.tickBackgroundColor}; + height: ${(props) => props.theme.tickHeight}; + width: ${(props) => props.theme.tickWidth}; + border-radius: 18px; + left: ${(props) => `${props.stepPosition}%`}; +`; + const StyledTextInput = styled.div` margin-left: ${(props) => props.theme.inputMarginLeft}; label + .MuiInput-formControl { From 20dcf913b6e8ca4e707fcec4a3a684cd4bfdd636 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Mon, 22 Aug 2022 14:29:08 +0200 Subject: [PATCH 02/19] Changing styles to make it more similar --- lib/src/slider/Slider.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index e932e08e4..9d755cf5c 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -201,7 +201,7 @@ const HelperText = styled.span` `; const Slider = styled.input` - width: 99%; + width: 100%; height: ${(props) => props.theme.trackLineThickness}; display: inline-block; vertical-align: middle; @@ -217,15 +217,15 @@ const Slider = styled.input` border-radius: 5px; &::-webkit-slider-runnable-track { -webkit-appearance: none; - z-index: 1; + box-shadow: none; border: none; background: transparent; - margin: 0px -6px; + margin: 0px -8px; } &::-webkit-slider-thumb { -webkit-appearance: none; - z-index: 1; + height: ${(props) => props.theme.thumbHeight}; width: ${(props) => props.theme.thumbWidth}; border-radius: 25px; @@ -241,6 +241,8 @@ const Slider = styled.input` &:hover { height: ${(props) => props.theme.hoverThumbHeight}; width: ${(props) => props.theme.hoverThumbWidth}; + transform: scale(1.16667); + transform-origin: center center; background: ${(props) => props.backgroundType === "dark" ? props.theme.hoverThumbBackgroundColor @@ -300,7 +302,7 @@ const SliderInputContainer = styled.div` const MarksContainer = styled.div` position: absolute; margin-right: 4px; - width: 99%; + width: 100%; top: 1px; pointer-events: none; height: 2px; From 0eb7539ef9713224d62d8f1e141cd079febb602d Mon Sep 17 00:00:00 2001 From: Jialecl Date: Tue, 23 Aug 2022 12:58:29 +0200 Subject: [PATCH 03/19] repositioning slider --- lib/src/slider/Slider.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 9d755cf5c..94517629c 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -207,7 +207,7 @@ const Slider = styled.input` vertical-align: middle; -webkit-appearance: none; background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.totalLineColorOnDark : props.theme.totalLineColor}; + props.backgroundType === "dark" ? props.theme.totalLineColorOnDark + "61" : props.theme.totalLineColor + "61"}; background-image: ${(props) => props.backgroundType === "dark" ? `linear-gradient(${props.theme.trackLineColorOnDark}, ${props.theme.trackLineColorOnDark})` @@ -237,6 +237,7 @@ const Slider = styled.input` props.backgroundType === "dark" ? props.theme.activeThumbBackgroundColor : props.theme.activeThumbBackgroundColorOnDark}; + transform: scale(1.16667); } &:hover { height: ${(props) => props.theme.hoverThumbHeight}; @@ -297,13 +298,15 @@ const SliderInputContainer = styled.div` display: flex; align-items: center; justify-content: center; + padding-top: 1px; + margin-right: -2px; `; const MarksContainer = styled.div` position: absolute; margin-right: 4px; width: 100%; - top: 1px; + top: 2px; pointer-events: none; height: 2px; `; From 6d05d875a2c6edd60e3a48f370f43693f271565d Mon Sep 17 00:00:00 2001 From: Jialecl Date: Wed, 24 Aug 2022 15:06:42 +0200 Subject: [PATCH 04/19] adding disabled andfixing event test --- lib/src/slider/Slider.test.js | 4 +- lib/src/slider/Slider.tsx | 77 ++++++++++++++++++++++++++--------- 2 files changed, 61 insertions(+), 20 deletions(-) diff --git a/lib/src/slider/Slider.test.js b/lib/src/slider/Slider.test.js index 52111db17..b2b93a83f 100644 --- a/lib/src/slider/Slider.test.js +++ b/lib/src/slider/Slider.test.js @@ -61,9 +61,11 @@ describe("Slider component tests", () => { ); act(() => { fireEvent.mouseDown(getByRole("slider")); + }); + act(() => { fireEvent.mouseUp(getByRole("slider")); }); - expect(onDragEnd).toHaveBeenCalled(); + expect(onDragEnd).toHaveBeenCalledTimes(1); }); test("Calls correct function labelFormatCallback", () => { const labelFormatCallback = jest.fn((x) => `${x}$`); diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 94517629c..1cd3327a7 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -51,7 +51,7 @@ const DxcSlider = ({ let index = 0; const range = maxValue - minValue; while (index <= numberOfMarks) { - ticks.push(); + ticks.push(); index++; } return ticks; @@ -101,6 +101,7 @@ const DxcSlider = ({ )} = 0 && value) || innerValue} min={minValue} @@ -207,17 +208,41 @@ const Slider = styled.input` vertical-align: middle; -webkit-appearance: none; background-color: ${(props) => - props.backgroundType === "dark" ? props.theme.totalLineColorOnDark + "61" : props.theme.totalLineColor + "61"}; + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledTotalLineColorOnDark + "61" + : props.theme.disabledTotalLineColor + "61" + : props.backgroundType === "dark" + ? props.theme.totalLineColorOnDark + "61" + : props.theme.totalLineColor + "61"}; background-image: ${(props) => - props.backgroundType === "dark" + props.disabled + ? props.backgroundType === "dark" + ? `linear-gradient(${props.theme.disabledTrackLineColorOnDark}, ${props.theme.disabledTrackLineColorOnDark})` + : `linear-gradient(${props.theme.disabledTrackLineColor}, ${props.theme.disabledTrackLineColor})` + : props.backgroundType === "dark" ? `linear-gradient(${props.theme.trackLineColorOnDark}, ${props.theme.trackLineColorOnDark})` : `linear-gradient(${props.theme.trackLineColor}, ${props.theme.trackLineColor})`}; background-repeat: no-repeat; background-size: ${(props) => ((props.value - props.min) * 100) / (props.max - props.min) + "% 100%"}; border-radius: 5px; + cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; + &:focus { + &::-webkit-slider-thumb { + outline: ${(props) => + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledFocusColorOnDark + : props.theme.disabledFocusColor + : props.backgroundType === "dark" + ? props.theme.focusColorOnDark + : props.theme.focusColor} + auto 1px; + outline-offset: 2px; + } + } &::-webkit-slider-runnable-track { -webkit-appearance: none; - box-shadow: none; border: none; background: transparent; @@ -225,13 +250,17 @@ const Slider = styled.input` } &::-webkit-slider-thumb { -webkit-appearance: none; - height: ${(props) => props.theme.thumbHeight}; width: ${(props) => props.theme.thumbWidth}; border-radius: 25px; background: ${(props) => - props.backgroundType === "dark" ? props.theme.thumbBackgroundColorOnDark : props.theme.thumbBackgroundColor}; - cursor: pointer; + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledThumbBackgroundColorOnDark + : props.theme.disabledThumbBackgroundColor + : props.backgroundType === "dark" + ? props.theme.thumbBackgroundColorOnDark + : props.theme.thumbBackgroundColor}; &:active { background: ${(props) => props.backgroundType === "dark" @@ -240,14 +269,18 @@ const Slider = styled.input` transform: scale(1.16667); } &:hover { - height: ${(props) => props.theme.hoverThumbHeight}; - width: ${(props) => props.theme.hoverThumbWidth}; - transform: scale(1.16667); - transform-origin: center center; - background: ${(props) => - props.backgroundType === "dark" - ? props.theme.hoverThumbBackgroundColor - : props.theme.hoverThumbBackgroundColorOnDark}; + ${(props) => { + if (!props.disabled) { + return `height: ${(props) => props.theme.hoverThumbHeight}; + width: ${(props) => props.theme.hoverThumbWidth}; + transform: scale(1.16667); + transform-origin: center center; + background: ${(props) => + props.backgroundType === "dark" + ? props.theme.hoverThumbBackgroundColor + : props.theme.hoverThumbBackgroundColorOnDark};`; + } + }} } } `; @@ -295,10 +328,10 @@ const MaxLabelContainer = styled.span` const SliderInputContainer = styled.div` position: relative; width: 100%; + height: 24px; display: flex; align-items: center; justify-content: center; - padding-top: 1px; margin-right: -2px; `; @@ -306,15 +339,21 @@ const MarksContainer = styled.div` position: absolute; margin-right: 4px; width: 100%; - top: 2px; + top: calc(50% - 1px); pointer-events: none; height: 2px; `; -const TickMark = styled.span<{ stepPosition: number }>` +const TickMark = styled.span<{ stepPosition: number; disabled: boolean }>` position: absolute; background: ${(props) => - props.backgroundType === "dark" ? props.theme.tickBackgroundColorOnDark : props.theme.tickBackgroundColor}; + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledTickBackgroundColorOnDark + : props.theme.disabledTickBackgroundColor + : props.backgroundType === "dark" + ? props.theme.tickBackgroundColorOnDark + : props.theme.tickBackgroundColor}; height: ${(props) => props.theme.tickHeight}; width: ${(props) => props.theme.tickWidth}; border-radius: 18px; From e0fb413608998085062209ead4ac36f7e7327544 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Thu, 25 Aug 2022 11:35:18 +0200 Subject: [PATCH 05/19] fixing hover on disable --- lib/src/slider/Slider.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 1cd3327a7..5290f3ef6 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -117,6 +117,7 @@ const DxcSlider = ({ onChange={handleSliderChange} onMouseUp={handleSliderOnChangeCommited} onMouseDown={handleSliderDragging} + backgroundType={backgroundType} /> {marks && {tickMarks}} @@ -264,21 +265,22 @@ const Slider = styled.input` &:active { background: ${(props) => props.backgroundType === "dark" - ? props.theme.activeThumbBackgroundColor - : props.theme.activeThumbBackgroundColorOnDark}; + ? props.theme.activeThumbBackgroundColorOnDark + : props.theme.activeThumbBackgroundColor}; transform: scale(1.16667); } &:hover { ${(props) => { if (!props.disabled) { - return `height: ${(props) => props.theme.hoverThumbHeight}; - width: ${(props) => props.theme.hoverThumbWidth}; + return `height: ${props.theme.hoverThumbHeight}; + width: ${props.theme.hoverThumbWidth}; transform: scale(1.16667); transform-origin: center center; - background: ${(props) => + background: ${ props.backgroundType === "dark" - ? props.theme.hoverThumbBackgroundColor - : props.theme.hoverThumbBackgroundColorOnDark};`; + ? props.theme.hoverThumbBackgroundColorOnDark + : props.theme.hoverThumbBackgroundColor + };`; } }} } From 0c5bd2a931687174cde0cca47a2e414039e9835b Mon Sep 17 00:00:00 2001 From: Jialecl Date: Thu, 25 Aug 2022 14:51:48 +0200 Subject: [PATCH 06/19] repositioning marks --- lib/src/slider/Slider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 5290f3ef6..7e97f2217 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -341,7 +341,7 @@ const MarksContainer = styled.div` position: absolute; margin-right: 4px; width: 100%; - top: calc(50% - 1px); + top: calc(50% - 2px); pointer-events: none; height: 2px; `; From 4afda228aade85f854915ff8b166c754eae47c64 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Fri, 26 Aug 2022 11:38:18 +0200 Subject: [PATCH 07/19] testing slider positioning --- lib/src/slider/Slider.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 7e97f2217..dbe0b8499 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -227,6 +227,7 @@ const Slider = styled.input` background-repeat: no-repeat; background-size: ${(props) => ((props.value - props.min) * 100) / (props.max - props.min) + "% 100%"}; border-radius: 5px; + z-index: 1; cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; &:focus { &::-webkit-slider-thumb { @@ -339,11 +340,12 @@ const SliderInputContainer = styled.div` const MarksContainer = styled.div` position: absolute; - margin-right: 4px; + margin-right: 6px; width: 100%; top: calc(50% - 2px); pointer-events: none; height: 2px; + margin-left: 3px; `; const TickMark = styled.span<{ stepPosition: number; disabled: boolean }>` From c63be4bf5a410e50a4f4306690f5603d23018035 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Fri, 26 Aug 2022 14:37:40 +0200 Subject: [PATCH 08/19] adding min witdh to slider --- lib/src/slider/Slider.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index dbe0b8499..82f3df002 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -204,6 +204,7 @@ const HelperText = styled.span` const Slider = styled.input` width: 100%; + min-width: 240px; height: ${(props) => props.theme.trackLineThickness}; display: inline-block; vertical-align: middle; From 535442a6fc72384c60e2f13154a8ad1c546db0d1 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Wed, 31 Aug 2022 13:24:45 +0200 Subject: [PATCH 09/19] Adding states to firefox --- lib/src/slider/Slider.tsx | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 82f3df002..2658725f2 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -231,6 +231,7 @@ const Slider = styled.input` z-index: 1; cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; &:focus { + outline: none; &::-webkit-slider-thumb { outline: ${(props) => props.disabled @@ -243,6 +244,18 @@ const Slider = styled.input` auto 1px; outline-offset: 2px; } + &::-moz-range-thumb { + outline: ${(props) => + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledFocusColorOnDark + : props.theme.disabledFocusColor + : props.backgroundType === "dark" + ? props.theme.focusColorOnDark + : props.theme.focusColor} + auto 1px; + outline-offset: 2px; + } } &::-webkit-slider-runnable-track { -webkit-appearance: none; @@ -251,8 +264,54 @@ const Slider = styled.input` background: transparent; margin: 0px -8px; } + &::-webkit-slider-thumb { -webkit-appearance: none; + border: none; + height: ${(props) => props.theme.thumbHeight}; + width: ${(props) => props.theme.thumbWidth}; + border-radius: 25px; + background: ${(props) => + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledThumbBackgroundColorOnDark + : props.theme.disabledThumbBackgroundColor + : props.backgroundType === "dark" + ? props.theme.thumbBackgroundColorOnDark + : props.theme.thumbBackgroundColor}; + &:active { + background: ${(props) => + props.backgroundType === "dark" + ? props.theme.activeThumbBackgroundColorOnDark + : props.theme.activeThumbBackgroundColor}; + transform: scale(1.16667); + } + &:hover { + ${(props) => { + if (!props.disabled) { + return `height: ${props.theme.hoverThumbHeight}; + width: ${props.theme.hoverThumbWidth}; + transform: scale(1.16667); + transform-origin: center center; + background: ${ + props.backgroundType === "dark" + ? props.theme.hoverThumbBackgroundColorOnDark + : props.theme.hoverThumbBackgroundColor + };`; + } + }} + } + } + &::-moz-range-track { + -webkit-appearance: none; + box-shadow: none; + border: none; + background: #fabada; + width: 105%; + } + &::-moz-range-thumb { + -webkit-appearance: none; + border: none; height: ${(props) => props.theme.thumbHeight}; width: ${(props) => props.theme.thumbWidth}; border-radius: 25px; @@ -286,6 +345,10 @@ const Slider = styled.input` } }} } + &:-moz-focusring { + outline: 1px solid white; + outline-offset: -1px; + } } `; From c63cb88103fd9e6a2aa1f0db07f643e4c04a18e5 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Wed, 31 Aug 2022 14:20:43 +0200 Subject: [PATCH 10/19] fixing some firefox styles --- lib/src/slider/Slider.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 2658725f2..7212dab67 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -306,8 +306,7 @@ const Slider = styled.input` -webkit-appearance: none; box-shadow: none; border: none; - background: #fabada; - width: 105%; + background: transparent; } &::-moz-range-thumb { -webkit-appearance: none; @@ -404,12 +403,11 @@ const SliderInputContainer = styled.div` const MarksContainer = styled.div` position: absolute; - margin-right: 6px; + margin: 0px 5px; width: 100%; top: calc(50% - 2px); pointer-events: none; height: 2px; - margin-left: 3px; `; const TickMark = styled.span<{ stepPosition: number; disabled: boolean }>` From e0add00e5b999f8349ff4045e68eaedfe8c8d278 Mon Sep 17 00:00:00 2001 From: Jialecl Date: Thu, 1 Sep 2022 11:18:52 +0200 Subject: [PATCH 11/19] fixing firefox marks container styles --- lib/src/slider/Slider.tsx | 81 +++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 7212dab67..91c8fe275 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -84,6 +84,8 @@ const DxcSlider = ({ } }; + const isFirefox = navigator.userAgent.indexOf("Firefox") !== -1; + return ( @@ -119,7 +121,11 @@ const DxcSlider = ({ onMouseDown={handleSliderDragging} backgroundType={backgroundType} /> - {marks && {tickMarks}} + {marks && ( + + {tickMarks} + + )} {showLimitsValues && ( @@ -154,6 +160,18 @@ const calculateWidth = (margin, size) => ? `calc(${sizes[size]} - ${getMargin(margin, "left")} - ${getMargin(margin, "right")})` : sizes[size]; +const getChromeStyles = () => { + return ` + width: 100%; + margin-right: 4px;`; +}; + +const getFireFoxStyles = () => { + return ` + width: calc(100% - 16px); + margin-right: 3px;`; +}; + const Container = styled.div` display: flex; flex-direction: column; @@ -228,35 +246,7 @@ const Slider = styled.input` background-repeat: no-repeat; background-size: ${(props) => ((props.value - props.min) * 100) / (props.max - props.min) + "% 100%"}; border-radius: 5px; - z-index: 1; cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; - &:focus { - outline: none; - &::-webkit-slider-thumb { - outline: ${(props) => - props.disabled - ? props.backgroundType === "dark" - ? props.theme.disabledFocusColorOnDark - : props.theme.disabledFocusColor - : props.backgroundType === "dark" - ? props.theme.focusColorOnDark - : props.theme.focusColor} - auto 1px; - outline-offset: 2px; - } - &::-moz-range-thumb { - outline: ${(props) => - props.disabled - ? props.backgroundType === "dark" - ? props.theme.disabledFocusColorOnDark - : props.theme.disabledFocusColor - : props.backgroundType === "dark" - ? props.theme.focusColorOnDark - : props.theme.focusColor} - auto 1px; - outline-offset: 2px; - } - } &::-webkit-slider-runnable-track { -webkit-appearance: none; box-shadow: none; @@ -344,9 +334,32 @@ const Slider = styled.input` } }} } - &:-moz-focusring { - outline: 1px solid white; - outline-offset: -1px; + } + &:focus { + outline: none; + &::-webkit-slider-thumb { + outline: ${(props) => + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledFocusColorOnDark + : props.theme.disabledFocusColor + : props.backgroundType === "dark" + ? props.theme.focusColorOnDark + : props.theme.focusColor} + auto 1px; + outline-offset: 2px; + } + &::-moz-range-thumb { + outline: ${(props) => + props.disabled + ? props.backgroundType === "dark" + ? props.theme.disabledFocusColorOnDark + : props.theme.disabledFocusColor + : props.backgroundType === "dark" + ? props.theme.focusColorOnDark + : props.theme.focusColor} + auto 1px; + outline-offset: 2px; } } `; @@ -402,12 +415,12 @@ const SliderInputContainer = styled.div` `; const MarksContainer = styled.div` + ${(props) => (props.isFirefox ? getFireFoxStyles() : getChromeStyles())} position: absolute; - margin: 0px 5px; - width: 100%; top: calc(50% - 2px); pointer-events: none; height: 2px; + z-index: 1; `; const TickMark = styled.span<{ stepPosition: number; disabled: boolean }>` From db651b94e8d8e19c76fa21c84e2cb7e28269374f Mon Sep 17 00:00:00 2001 From: Jialecl Date: Fri, 2 Sep 2022 09:21:01 +0200 Subject: [PATCH 12/19] Positioning of the slider --- lib/src/slider/Slider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 91c8fe275..1a1fefba7 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -246,6 +246,7 @@ const Slider = styled.input` background-repeat: no-repeat; background-size: ${(props) => ((props.value - props.min) * 100) / (props.max - props.min) + "% 100%"}; border-radius: 5px; + z-index: 1; cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; &::-webkit-slider-runnable-track { -webkit-appearance: none; @@ -412,6 +413,7 @@ const SliderInputContainer = styled.div` align-items: center; justify-content: center; margin-right: -2px; + padding-top: 1px; `; const MarksContainer = styled.div` @@ -420,7 +422,6 @@ const MarksContainer = styled.div` top: calc(50% - 2px); pointer-events: none; height: 2px; - z-index: 1; `; const TickMark = styled.span<{ stepPosition: number; disabled: boolean }>` From 9500a34ed2db7f03c70689c48ce1c0a4ba91388c Mon Sep 17 00:00:00 2001 From: Jialecl Date: Fri, 2 Sep 2022 15:12:58 +0200 Subject: [PATCH 13/19] Adding typing to styled components --- lib/src/slider/Slider.tsx | 47 +++++++++++++++++++++++---------------- lib/src/slider/types.ts | 4 ++-- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 1a1fefba7..f71f55011 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React, { useState, useMemo, useContext } from "react"; import styled, { ThemeProvider } from "styled-components"; import DxcTextInput from "../text-input/TextInput"; @@ -6,7 +5,7 @@ import { spaces } from "../common/variables.js"; import { getMargin } from "../common/utils.js"; import useTheme from "../useTheme"; import BackgroundColorContext from "../BackgroundColorContext"; -import SliderPropsType from "./types"; +import SliderPropsType, { Margin, Space } from "./types"; import { v4 as uuidv4 } from "uuid"; const DxcSlider = ({ @@ -51,13 +50,19 @@ const DxcSlider = ({ let index = 0; const range = maxValue - minValue; while (index <= numberOfMarks) { - ticks.push(); + ticks.push( + + ); index++; } return ticks; }, [minValue, maxValue, step]); - const handleSliderChange = (event, newValue) => { + const handleSliderChange = (event) => { const valueToCheck = event.target.value; (valueToCheck !== value || valueToCheck !== innerValue) && setInnerValue(valueToCheck); onChange?.(valueToCheck); @@ -95,7 +100,7 @@ const DxcSlider = ({ {helperText} - + {showLimitsValues && ( {minLabel} @@ -109,7 +114,7 @@ const DxcSlider = ({ min={minValue} max={maxValue} step={step} - marks={marks || []} + marks={marks} disabled={disabled} aria-labelledby={labelId} aria-orientation="horizontal" @@ -121,11 +126,7 @@ const DxcSlider = ({ onMouseDown={handleSliderDragging} backgroundType={backgroundType} /> - {marks && ( - - {tickMarks} - - )} + {marks && {tickMarks}} {showLimitsValues && ( @@ -172,7 +173,7 @@ const getFireFoxStyles = () => { margin-right: 3px;`; }; -const Container = styled.div` +const Container = styled.div<{ margin: Margin | Space; size: "medium" | "large" | "fillParent" }>` display: flex; flex-direction: column; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -187,7 +188,7 @@ const Container = styled.div` width: ${(props) => calculateWidth(props.margin, props.size)}; `; -const Label = styled.label` +const Label = styled.label<{ disabled: boolean; backgroundType: "dark" | "light" }>` color: ${(props) => props.disabled ? props.backgroundType === "dark" @@ -204,7 +205,7 @@ const Label = styled.label` line-height: ${(props) => props.theme.labelLineHeight}; `; -const HelperText = styled.span` +const HelperText = styled.span<{ disabled: boolean; backgroundType: "dark" | "light" }>` color: ${(props) => props.disabled ? props.backgroundType === "dark" @@ -220,7 +221,15 @@ const HelperText = styled.span` line-height: ${(props) => props.theme.helperTextLineHeight}; `; -const Slider = styled.input` +const Slider = styled.input<{ + disabled: boolean; + backgroundType: "dark" | "light"; + value: number; + min: number; + max: number; + marks: boolean; + onChange: (event: React.ChangeEventHandler) => void; +}>` width: 100%; min-width: 240px; height: ${(props) => props.theme.trackLineThickness}; @@ -371,7 +380,7 @@ const SliderContainer = styled.div` align-items: center; `; -const MinLabelContainer = styled.span` +const MinLabelContainer = styled.span<{ disabled: boolean; backgroundType: "dark" | "light" }>` color: ${(props) => props.disabled ? props.theme.disabledLimitValuesFontColor @@ -388,7 +397,7 @@ const MinLabelContainer = styled.span` margin-right: ${(props) => props.theme.floorLabelMarginRight}; `; -const MaxLabelContainer = styled.span` +const MaxLabelContainer = styled.span<{ disabled: boolean; backgroundType: "dark" | "light"; step: number }>` color: ${(props) => props.disabled ? props.theme.disabledLimitValuesFontColor @@ -416,7 +425,7 @@ const SliderInputContainer = styled.div` padding-top: 1px; `; -const MarksContainer = styled.div` +const MarksContainer = styled.div<{ isFirefox: boolean }>` ${(props) => (props.isFirefox ? getFireFoxStyles() : getChromeStyles())} position: absolute; top: calc(50% - 2px); @@ -424,7 +433,7 @@ const MarksContainer = styled.div` height: 2px; `; -const TickMark = styled.span<{ stepPosition: number; disabled: boolean }>` +const TickMark = styled.span<{ stepPosition: number; disabled: boolean; backgroundType: "dark" | "light" }>` position: absolute; background: ${(props) => props.disabled diff --git a/lib/src/slider/types.ts b/lib/src/slider/types.ts index 0eb98b4ac..263cc7848 100644 --- a/lib/src/slider/types.ts +++ b/lib/src/slider/types.ts @@ -1,5 +1,5 @@ -type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; -type Margin = { +export type Space = "xxsmall" | "xsmall" | "small" | "medium" | "large" | "xlarge" | "xxlarge"; +export type Margin = { top?: Space; bottom?: Space; left?: Space; From 16c1906bdf65ce250a05b41e2d7671b77749eebf Mon Sep 17 00:00:00 2001 From: Jialecl Date: Thu, 15 Sep 2022 09:48:19 +0200 Subject: [PATCH 14/19] Adding changes in tsx based on the review --- lib/src/slider/Slider.stories.tsx | 8 +++- lib/src/slider/Slider.tsx | 72 +++++++++++++++---------------- 2 files changed, 42 insertions(+), 38 deletions(-) diff --git a/lib/src/slider/Slider.stories.tsx b/lib/src/slider/Slider.stories.tsx index 773c6e326..086696dc3 100644 --- a/lib/src/slider/Slider.stories.tsx +++ b/lib/src/slider/Slider.stories.tsx @@ -171,7 +171,13 @@ export const Chromatic = () => ( - <DxcSlider label="Slider" helperText="Help message" showLimitsValues labelFormatCallback={labelFormat} size="large" /> + <DxcSlider + label="Slider" + helperText="Help message" + showLimitsValues + labelFormatCallback={labelFormat} + size="large" + /> </ExampleContainer> </> ); diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 0fbf3dc58..a471fbb58 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -49,17 +49,21 @@ const DxcSlider = ({ const numberOfMarks = Math.floor(maxValue / step - minValue / step); let index = 0; const range = maxValue - minValue; - while (index <= numberOfMarks) { - ticks.push( - <TickMark - disabled={disabled} - stepPosition={((step * index) / range) * 100} - backgroundType={backgroundType} - ></TickMark> - ); - index++; + if (marks) { + while (index <= numberOfMarks) { + ticks.push( + <TickMark + disabled={disabled} + stepPosition={((step * index) / range) * 100} + backgroundType={backgroundType} + ></TickMark> + ); + index++; + } + return ticks; + } else { + return null; } - return ticks; }, [minValue, maxValue, step]); const handleSliderChange = (event) => { @@ -68,7 +72,7 @@ const DxcSlider = ({ onChange?.(valueToCheck); }; - const handleSliderDragging = (event) => { + const handleSliderDragging = () => { setDragging(true); }; @@ -173,7 +177,9 @@ const getFireFoxStyles = () => { margin-right: 3px;`; }; -const Container = styled.div<{ margin: Margin | Space; size: "medium" | "large" | "fillParent" }>` +type ContainerProps = { margin: Margin | Space; size: "medium" | "large" | "fillParent" }; + +const Container = styled.div<ContainerProps>` display: flex; flex-direction: column; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -188,7 +194,9 @@ const Container = styled.div<{ margin: Margin | Space; size: "medium" | "large" width: ${(props) => calculateWidth(props.margin, props.size)}; `; -const Label = styled.label<{ disabled: boolean; backgroundType: "dark" | "light" }>` +type LabelProps = { disabled: boolean; backgroundType: "dark" | "light" }; + +const Label = styled.label<LabelProps>` color: ${(props) => props.disabled ? props.backgroundType === "dark" @@ -205,7 +213,7 @@ const Label = styled.label<{ disabled: boolean; backgroundType: "dark" | "light" line-height: ${(props) => props.theme.labelLineHeight}; `; -const HelperText = styled.span<{ disabled: boolean; backgroundType: "dark" | "light" }>` +const HelperText = styled.span<LabelProps>` color: ${(props) => props.disabled ? props.backgroundType === "dark" @@ -214,6 +222,7 @@ const HelperText = styled.span<{ disabled: boolean; backgroundType: "dark" | "li : props.backgroundType === "dark" ? props.theme.helperTextFontColorOnDark : props.theme.helperTextFontColor}; + font-family: ${(props) => props.theme.fontFamily}; font-size: ${(props) => props.theme.helperTextFontSize}; font-style: ${(props) => props.theme.helperTextFontStyle}; @@ -221,15 +230,16 @@ const HelperText = styled.span<{ disabled: boolean; backgroundType: "dark" | "li line-height: ${(props) => props.theme.helperTextLineHeight}; `; -const Slider = styled.input<{ +type SliderProps = { disabled: boolean; backgroundType: "dark" | "light"; value: number; min: number; max: number; marks: boolean; - onChange: (event: React.ChangeEventHandler<HTMLInputElement>) => void; -}>` +}; + +const Slider = styled.input<SliderProps>` width: 100%; min-width: 240px; height: ${(props) => props.theme.trackLineThickness}; @@ -380,7 +390,7 @@ const SliderContainer = styled.div` align-items: center; `; -const MinLabelContainer = styled.span<{ disabled: boolean; backgroundType: "dark" | "light" }>` +const LimitLabelContainer = styled.span<LabelProps>` color: ${(props) => props.disabled ? props.theme.disabledLimitValuesFontColor @@ -394,23 +404,13 @@ const MinLabelContainer = styled.span<{ disabled: boolean; backgroundType: "dark font-weight: ${(props) => props.theme.limitValuesFontWeight}; letter-spacing: ${(props) => props.theme.limitValuesFontLetterSpacing}; white-space: nowrap; - margin-right: ${(props) => props.theme.floorLabelMarginRight}; `; -const MaxLabelContainer = styled.span<{ disabled: boolean; backgroundType: "dark" | "light"; step: number }>` - color: ${(props) => - props.disabled - ? props.theme.disabledLimitValuesFontColor - : props.backgroundType === "dark" - ? props.theme.limitValuesFontColorOnDark - : props.theme.limitValuesFontColor}; +const MinLabelContainer = styled(LimitLabelContainer)` + margin-right: ${(props) => props.theme.floorLabelMarginRight}; +`; - font-family: ${(props) => props.theme.fontFamily}; - font-size: ${(props) => props.theme.limitValuesFontSize}; - font-style: ${(props) => props.theme.limitValuesFontStyle}; - font-weight: ${(props) => props.theme.limitValuesFontWeight}; - letter-spacing: ${(props) => props.theme.limitValuesFontLetterSpacing}; - white-space: nowrap; +const MaxLabelContainer = styled(LimitLabelContainer)<{ step: number }>` margin-left: ${(props) => (props.step === 1 ? props.theme.ceilLabelMarginLeft : "1.25rem")}; `; @@ -428,9 +428,10 @@ const SliderInputContainer = styled.div` const MarksContainer = styled.div<{ isFirefox: boolean }>` ${(props) => (props.isFirefox ? getFireFoxStyles() : getChromeStyles())} position: absolute; - top: calc(50% - 2px); pointer-events: none; - height: 2px; + height: 100%; + display: flex; + align-items: center; `; const TickMark = styled.span<{ stepPosition: number; disabled: boolean; backgroundType: "dark" | "light" }>` @@ -451,9 +452,6 @@ const TickMark = styled.span<{ stepPosition: number; disabled: boolean; backgrou const StyledTextInput = styled.div` margin-left: ${(props) => props.theme.inputMarginLeft}; - label + .MuiInput-formControl { - margin-top: 2px; - } max-width: 70px; `; From 711a5597e4b2a84dffc461087e29b1ecc6469c16 Mon Sep 17 00:00:00 2001 From: Jialecl <jialestrabajos@gmail.com> Date: Thu, 15 Sep 2022 09:51:16 +0200 Subject: [PATCH 15/19] Adding types to TickMark elements --- lib/src/slider/Slider.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index a471fbb58..896bc9c5c 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -425,7 +425,9 @@ const SliderInputContainer = styled.div` padding-top: 1px; `; -const MarksContainer = styled.div<{ isFirefox: boolean }>` +type MarksContainerProps = { isFirefox: boolean }; + +const MarksContainer = styled.div<MarksContainerProps>` ${(props) => (props.isFirefox ? getFireFoxStyles() : getChromeStyles())} position: absolute; pointer-events: none; @@ -434,7 +436,9 @@ const MarksContainer = styled.div<{ isFirefox: boolean }>` align-items: center; `; -const TickMark = styled.span<{ stepPosition: number; disabled: boolean; backgroundType: "dark" | "light" }>` +type TickMarkProps = { stepPosition: number; disabled: boolean; backgroundType: "dark" | "light" }; + +const TickMark = styled.span<TickMarkProps>` position: absolute; background: ${(props) => props.disabled From 921dfba313adeb605a993bd9e8119daf189437d2 Mon Sep 17 00:00:00 2001 From: Jialecl <jialestrabajos@gmail.com> Date: Mon, 19 Sep 2022 11:54:00 +0200 Subject: [PATCH 16/19] Improving accessibility and interaction tests --- lib/src/slider/Slider.test.js | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/src/slider/Slider.test.js b/lib/src/slider/Slider.test.js index 91420479e..77dc03049 100644 --- a/lib/src/slider/Slider.test.js +++ b/lib/src/slider/Slider.test.js @@ -18,6 +18,19 @@ describe("Slider component tests", () => { expect(slider.getAttribute("aria-valuenow")).toBe("30"); expect(input.value).toBe("30"); }); + test("Slider correct limit values", () => { + const { getByRole, getByText } = render( + <DxcSlider defaultValue={125} minValue={30} maxValue={125} showLimitsValues /> + ); + const slider = getByRole("slider"); + expect(slider.getAttribute("aria-valuemin")).toBe("30"); + expect(slider.getAttribute("aria-valuemax")).toBe("125"); + userEvent.tab(); + fireEvent.keyDown(slider, { key: "ArrowRight", code: "ArrowRight", keyCode: 39, charCode: 39 }); + expect(slider.getAttribute("aria-valuenow")).toBe("125"); + expect(getByText("30")).toBeTruthy(); + expect(getByText("125")).toBeTruthy(); + }); test("Calls correct function onChange in controlled slider", () => { const onChange = jest.fn(); const { getByRole } = render( @@ -44,7 +57,7 @@ describe("Slider component tests", () => { expect(getByRole("slider").getAttribute("aria-valuenow")).toBe("25"); expect(getByRole("textbox").value).toBe("25"); }); - test("Disabled slider have disabled input", () => { + test("Disabled slider have disabled input and slider", () => { const onChange = jest.fn(); const { getByRole } = render( <DxcSlider minValue={0} maxValue={100} onChange={onChange} showLimitsValues disabled showInput value={13} /> @@ -54,19 +67,19 @@ describe("Slider component tests", () => { }); expect(getByRole("textbox").hasAttribute("disabled")).toBeTruthy(); expect(getByRole("textbox").value).toBe("13"); + expect(getByRole("slider").hasAttribute("disabled")).toBeTruthy(); }); test("Calls correct function onDragEnd", () => { const onDragEnd = jest.fn(); - const { getByRole } = render( - <DxcSlider minValue={0} maxValue={100} showLimitsValues showInput onDragEnd={onDragEnd} value={25} /> - ); + const { getByRole } = render(<DxcSlider minValue={0} maxValue={150} onDragEnd={onDragEnd} showInput />); + const slider = getByRole("slider"); act(() => { - fireEvent.mouseDown(getByRole("slider")); + fireEvent.mouseDown(slider); }); act(() => { - fireEvent.mouseUp(getByRole("slider")); + fireEvent.mouseUp(slider, { target: { value: 120 } }); }); - expect(onDragEnd).toHaveBeenCalledTimes(1); + expect(onDragEnd).toHaveBeenCalledWith("120"); }); test("Calls correct function labelFormatCallback", () => { const labelFormatCallback = jest.fn((x) => `${x}$`); From 8e48317502d7ca3f629ca6e8d47a7a43cddbac8d Mon Sep 17 00:00:00 2001 From: Jialecl <jialestrabajos@gmail.com> Date: Tue, 20 Sep 2022 17:01:57 +0200 Subject: [PATCH 17/19] rename types + tests + remove uuid + disabled active thumb fix --- lib/src/slider/Slider.test.js | 19 ++++++++++++-- lib/src/slider/Slider.tsx | 47 +++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/lib/src/slider/Slider.test.js b/lib/src/slider/Slider.test.js index 77dc03049..e4b5d9af1 100644 --- a/lib/src/slider/Slider.test.js +++ b/lib/src/slider/Slider.test.js @@ -4,10 +4,12 @@ import userEvent from "@testing-library/user-event"; import DxcSlider from "./Slider"; describe("Slider component tests", () => { - test("Slider renders with correct text", () => { - const { getByText } = render(<DxcSlider minValue={0} maxValue={100} showLimitsValues />); + test("Slider renders with correct text and label id", () => { + const { getByText, getByRole } = render(<DxcSlider label="label" minValue={0} maxValue={100} showLimitsValues />); expect(getByText("0")).toBeTruthy(); expect(getByText("100")).toBeTruthy(); + const sliderId = getByText("label").getAttribute("id"); + expect(getByRole("slider").getAttribute("aria-labelledby")).toBe(sliderId); }); test("Slider renders with correct initial value when it is uncontrolled", () => { const { getByRole } = render( @@ -81,6 +83,19 @@ describe("Slider component tests", () => { }); expect(onDragEnd).toHaveBeenCalledWith("120"); }); + test("Calls correct function onDragEnd when it is controlled", () => { + const onDragEnd = jest.fn(); + const { getByRole } = render(<DxcSlider minValue={0} maxValue={150} value={50} onDragEnd={onDragEnd} showInput />); + const slider = getByRole("slider"); + act(() => { + fireEvent.mouseDown(slider); + }); + act(() => { + fireEvent.mouseUp(slider, { target: { value: 120 } }); + }); + expect(onDragEnd).toHaveBeenCalledWith("120"); + expect(slider.getAttribute("aria-valuenow")).toBe("50"); + }); test("Calls correct function labelFormatCallback", () => { const labelFormatCallback = jest.fn((x) => `${x}$`); const { getByText } = render( diff --git a/lib/src/slider/Slider.tsx b/lib/src/slider/Slider.tsx index 896bc9c5c..f0f3c6a66 100644 --- a/lib/src/slider/Slider.tsx +++ b/lib/src/slider/Slider.tsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo, useContext } from "react"; +import React, { useState, useMemo, useContext, useId } from "react"; import styled, { ThemeProvider } from "styled-components"; import DxcTextInput from "../text-input/TextInput"; import { spaces } from "../common/variables.js"; @@ -6,7 +6,6 @@ import { getMargin } from "../common/utils.js"; import useTheme from "../useTheme"; import BackgroundColorContext from "../BackgroundColorContext"; import SliderPropsType, { Margin, Space } from "./types"; -import { v4 as uuidv4 } from "uuid"; const DxcSlider = ({ label = "", @@ -32,7 +31,7 @@ const DxcSlider = ({ const colorsTheme = useTheme(); const backgroundType = useContext(BackgroundColorContext); - const [labelId] = useState(`label-${uuidv4()}`); + const labelId = "slider" + useId(); const minLabel = useMemo( () => (labelFormatCallback ? labelFormatCallback(minValue) : minValue), @@ -111,7 +110,7 @@ const DxcSlider = ({ </MinLabelContainer> )} <SliderInputContainer> - <Slider + <SliderInput role="slider" type="range" value={value != null && value >= 0 ? value : innerValue} @@ -177,9 +176,9 @@ const getFireFoxStyles = () => { margin-right: 3px;`; }; -type ContainerProps = { margin: Margin | Space; size: "medium" | "large" | "fillParent" }; +type ContainerPropsType = { margin: Margin | Space; size: "medium" | "large" | "fillParent" }; -const Container = styled.div<ContainerProps>` +const Container = styled.div<ContainerPropsType>` display: flex; flex-direction: column; margin: ${(props) => (props.margin && typeof props.margin !== "object" ? spaces[props.margin] : "0px")}; @@ -194,9 +193,9 @@ const Container = styled.div<ContainerProps>` width: ${(props) => calculateWidth(props.margin, props.size)}; `; -type LabelProps = { disabled: boolean; backgroundType: "dark" | "light" }; +type LabelPropsType = { disabled: boolean; backgroundType: "dark" | "light" }; -const Label = styled.label<LabelProps>` +const Label = styled.label<LabelPropsType>` color: ${(props) => props.disabled ? props.backgroundType === "dark" @@ -213,7 +212,7 @@ const Label = styled.label<LabelProps>` line-height: ${(props) => props.theme.labelLineHeight}; `; -const HelperText = styled.span<LabelProps>` +const HelperText = styled.span<LabelPropsType>` color: ${(props) => props.disabled ? props.backgroundType === "dark" @@ -230,7 +229,7 @@ const HelperText = styled.span<LabelProps>` line-height: ${(props) => props.theme.helperTextLineHeight}; `; -type SliderProps = { +type SliderInputPropsType = { disabled: boolean; backgroundType: "dark" | "light"; value: number; @@ -239,7 +238,7 @@ type SliderProps = { marks: boolean; }; -const Slider = styled.input<SliderProps>` +const SliderInput = styled.input<SliderInputPropsType>` width: 100%; min-width: 240px; height: ${(props) => props.theme.trackLineThickness}; @@ -290,11 +289,17 @@ const Slider = styled.input<SliderProps>` ? props.theme.thumbBackgroundColorOnDark : props.theme.thumbBackgroundColor}; &:active { - background: ${(props) => - props.backgroundType === "dark" - ? props.theme.activeThumbBackgroundColorOnDark - : props.theme.activeThumbBackgroundColor}; - transform: scale(1.16667); + ${(props) => { + if (!props.disabled) { + return ` + background: ${ + props.backgroundType === "dark" + ? props.theme.activeThumbBackgroundColorOnDark + : props.theme.activeThumbBackgroundColor + }; + transform: scale(1.16667);`; + } + }} } &:hover { ${(props) => { @@ -390,7 +395,7 @@ const SliderContainer = styled.div` align-items: center; `; -const LimitLabelContainer = styled.span<LabelProps>` +const LimitLabelContainer = styled.span<LabelPropsType>` color: ${(props) => props.disabled ? props.theme.disabledLimitValuesFontColor @@ -425,9 +430,9 @@ const SliderInputContainer = styled.div` padding-top: 1px; `; -type MarksContainerProps = { isFirefox: boolean }; +type MarksContainerPropsType = { isFirefox: boolean }; -const MarksContainer = styled.div<MarksContainerProps>` +const MarksContainer = styled.div<MarksContainerPropsType>` ${(props) => (props.isFirefox ? getFireFoxStyles() : getChromeStyles())} position: absolute; pointer-events: none; @@ -436,9 +441,9 @@ const MarksContainer = styled.div<MarksContainerProps>` align-items: center; `; -type TickMarkProps = { stepPosition: number; disabled: boolean; backgroundType: "dark" | "light" }; +type TickMarkPropsType = { stepPosition: number; disabled: boolean; backgroundType: "dark" | "light" }; -const TickMark = styled.span<TickMarkProps>` +const TickMark = styled.span<TickMarkPropsType>` position: absolute; background: ${(props) => props.disabled From 27df01f093507ca9841d55243c498d1f0839be2e Mon Sep 17 00:00:00 2001 From: Jialecl <jialestrabajos@gmail.com> Date: Tue, 20 Sep 2022 17:11:23 +0200 Subject: [PATCH 18/19] adding accesibility check test --- lib/src/slider/Slider.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/slider/Slider.test.js b/lib/src/slider/Slider.test.js index e4b5d9af1..6d2c55391 100644 --- a/lib/src/slider/Slider.test.js +++ b/lib/src/slider/Slider.test.js @@ -10,6 +10,7 @@ describe("Slider component tests", () => { expect(getByText("100")).toBeTruthy(); const sliderId = getByText("label").getAttribute("id"); expect(getByRole("slider").getAttribute("aria-labelledby")).toBe(sliderId); + expect(getByRole("slider").getAttribute("aria-orientation")).toBe("horizontal"); }); test("Slider renders with correct initial value when it is uncontrolled", () => { const { getByRole } = render( From 80784d7897e317f5c514a3a27f5541899c36195f Mon Sep 17 00:00:00 2001 From: Jialecl <jialestrabajos@gmail.com> Date: Wed, 21 Sep 2022 08:59:23 +0200 Subject: [PATCH 19/19] added more info in test title --- lib/src/slider/Slider.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/slider/Slider.test.js b/lib/src/slider/Slider.test.js index 6d2c55391..8205be8ae 100644 --- a/lib/src/slider/Slider.test.js +++ b/lib/src/slider/Slider.test.js @@ -72,7 +72,7 @@ describe("Slider component tests", () => { expect(getByRole("textbox").value).toBe("13"); expect(getByRole("slider").hasAttribute("disabled")).toBeTruthy(); }); - test("Calls correct function onDragEnd", () => { + test("Calls correct function onDragEnd when it is uncontrolled", () => { const onDragEnd = jest.fn(); const { getByRole } = render(<DxcSlider minValue={0} maxValue={150} onDragEnd={onDragEnd} showInput />); const slider = getByRole("slider");