Skip to content

Commit

Permalink
fix: add hoverVisibility prop to Slider & fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
vadim-kudr committed Dec 4, 2024
1 parent 1fb7a93 commit 145c113
Show file tree
Hide file tree
Showing 45 changed files with 135 additions and 33 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions packages/plasma-b2c/api/plasma-b2c.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3543,6 +3543,7 @@ view?: string | undefined;
size?: "m" | "s" | "l" | undefined;
type?: "single" | undefined;
pointerSize?: "none" | "small" | "large" | undefined;
pointerVisibility: "onHover" | "always";
} & RefAttributes<HTMLDivElement>) | (SliderBaseProps & SliderInternalProps & {
onChange?: ((event: FormTypeNumber) => void) | undefined;
name: string;
Expand Down Expand Up @@ -3571,6 +3572,7 @@ view?: string | undefined;
size?: "m" | "s" | "l" | undefined;
type?: "single" | undefined;
pointerSize?: "none" | "small" | "large" | undefined;
pointerVisibility: "onHover" | "always";
} & RefAttributes<HTMLDivElement>) | (SliderBaseProps & SliderInternalProps & {
onChange?: ((value: number) => void) | undefined;
value: number;
Expand Down Expand Up @@ -3600,6 +3602,7 @@ view?: string | undefined;
size?: "m" | "s" | "l" | undefined;
type?: "single" | undefined;
pointerSize?: "none" | "small" | "large" | undefined;
pointerVisibility: "onHover" | "always";
} & RefAttributes<HTMLDivElement>) | (SliderBaseProps & SliderInternalProps & {
onChange?: ((value: number) => void) | undefined;
value: number;
Expand Down Expand Up @@ -3628,6 +3631,7 @@ view?: string | undefined;
size?: "m" | "s" | "l" | undefined;
type?: "single" | undefined;
pointerSize?: "none" | "small" | "large" | undefined;
pointerVisibility: "onHover" | "always";
} & RefAttributes<HTMLDivElement>) | (Omit<DoubleSliderProps, "onChange" | "defaultValue" | "value"> & {
onChange?: ((event: FormTypeString) => void) | undefined;
name?: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { FormTypeNumber } from '../../../../types/FormType';
import type { SingleSliderProps } from './Single.types';
import { Label, LabelContent, LabelWrapper, SingleWrapper, SliderBaseWrapper, StyledRangeValue } from './Single.styles';

const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(value, max));

export const SingleSlider: FC<SingleSliderProps> = ({
min,
max,
Expand All @@ -38,13 +40,16 @@ export const SingleSlider: FC<SingleSliderProps> = ({
size = 'm',
name,
pointerSize = 'small',
pointerVisibility = 'always',
orientation = 'horizontal',
reversed,
labelReversed,
...rest
}) => {
const isVertical = orientation === 'vertical';

const [isHovered, setIsHovered] = useState(false);

const [state, setState] = useState({
handlePosition: 0,
stepSize: 0,
Expand All @@ -56,7 +61,7 @@ export const SingleSlider: FC<SingleSliderProps> = ({
const [startOffset, setStartOffset] = useState(0);
const [endOffset, setEndOffset] = useState(0);

const innerValue = value ?? defaultValue ?? min;
const innerValue = clamp(value ?? defaultValue ?? min, min, max);
const [dragValue, setDragValue] = useState(innerValue);

const { stepSize } = state;
Expand Down Expand Up @@ -179,10 +184,27 @@ export const SingleSlider: FC<SingleSliderProps> = ({
[isVertical, min, max, reversed],
);

useEffect(() => {
if (value !== dragValue) {
const newValue = clamp(value ?? defaultValue ?? min, min, max);
const clampedValue = Math.max(min, Math.min(newValue, max));

setDragValue(clampedValue);
}
}, [value, defaultValue, dragValue, min, max]);

const labelVerticalPlacement = reversed ? 'bottom' : 'top';
const valuePlacement = sliderAlign === 'right' ? 'left' : 'right';
const settings = sizeData[size][pointerSize === 'large' ? 'large' : 'small'];

const onPointerEnter = () => {
setIsHovered(true);
};

const onPointerLeave = () => {
setIsHovered(false);
};

return (
<SingleWrapper
className={cx(
Expand All @@ -195,6 +217,8 @@ export const SingleSlider: FC<SingleSliderProps> = ({
labelVerticalPlacement === 'bottom' && classes.labelPlacementBottom,
labelReversed && classes.labelContentReversed,
)}
onPointerEnter={onPointerEnter}
onPointerLeave={onPointerLeave}
>
{hasLabelContent && (
<LabelWrapper>
Expand Down Expand Up @@ -227,10 +251,13 @@ export const SingleSlider: FC<SingleSliderProps> = ({
labelPlacement={labelPlacement}
rangeValuesPlacement={rangeValuesPlacement}
orientation={orientation}
reversed={reversed}
{...rest}
>
<Handler
size={pointerSize}
visibility={pointerVisibility}
isHovered={isHovered}
orientation={orientation}
stepSize={state.stepSize}
onChangeCommitted={onHandleChangeCommitted}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,11 @@ export type SingleSliderProps = SliderBaseProps &
* none - скрыть ползунок
*/
pointerSize?: 'small' | 'large' | 'none';

/**
* Условия появления ползунка
* @default small
* @description
*/
pointerVisibility: 'always' | 'onHover';
};
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ export const RailWrap = styled.div`

export const Fill = styled.div`
position: absolute;
width: 0;
height: 100%;
top: 0;
left: 0;
border-radius: var(--plasma-slider-rail-border-radius);
background: var(${tokens.fillColor});
width: 0;
`;

export const InputHidden = styled.input`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,17 @@ export const SliderBase: React.FC<PropsWithChildren<SliderViewProps>> = ({
rangeValuesPlacement,
onChange,
orientation,
reversed,
size,
sliderAlign,
settings = {},
}) => {
const { indent = 0.75, fontSizeMultiplier = 16 } = settings;

const ref = useRef<HTMLDivElement | null>(null);
const gap = indent * fontSizeMultiplier * 2;
const isVertical = orientation === 'vertical';

useEffect(() => {
const resizeHandler = () => {
if (ref.current) {
const railSize = isVertical ? ref.current.offsetHeight - gap : ref.current.offsetWidth - gap;
const railSize = isVertical ? ref.current.offsetHeight : ref.current.offsetWidth;
const totalSteps = max - min;

setStepSize(railSize / totalSteps);
Expand All @@ -44,7 +41,6 @@ export const SliderBase: React.FC<PropsWithChildren<SliderViewProps>> = ({
}, [
labelPlacement,
rangeValuesPlacement,
gap,
isVertical,
// для перерасчета размеров
size,
Expand All @@ -61,7 +57,7 @@ export const SliderBase: React.FC<PropsWithChildren<SliderViewProps>> = ({
const lastPos = isVertical ? e.clientY - y : e.clientX - x;
const sliderWidth = isVertical ? height : width;

const position = min + (lastPos / (sliderWidth - gap)) * (max - min);
const position = min + (lastPos / sliderWidth) * (max - min);
const result = Math.max(min, Math.min(max, position));

const data = isVertical ? { lastY: lastPos } : { lastX: lastPos };
Expand All @@ -71,7 +67,7 @@ export const SliderBase: React.FC<PropsWithChildren<SliderViewProps>> = ({
useIsomorphicLayoutEffect(() => {
const resizeHandler = () => {
if (ref.current) {
const railSize = isVertical ? ref.current.offsetHeight - gap : ref.current.offsetWidth - gap;
const railSize = isVertical ? ref.current.offsetHeight : ref.current.offsetWidth;
const totalSteps = max - min;

setStepSize(railSize / totalSteps);
Expand All @@ -82,11 +78,19 @@ export const SliderBase: React.FC<PropsWithChildren<SliderViewProps>> = ({
window.addEventListener('resize', resizeHandler);

return () => window.removeEventListener('resize', resizeHandler);
}, [min, max, setStepSize, gap, labelPlacement, rangeValuesPlacement, isVertical]);
}, [min, max, setStepSize, labelPlacement, rangeValuesPlacement, isVertical]);

const fillStyle = (() => {
if (isVertical && reversed) {
return { bottom: 0, height: `calc(100% - ${railFillWidth}px)`, top: 'auto', width: '100%' };
}

if (isVertical) {
return { bottom: `${railFillXPosition}px`, height: `${railFillWidth}px`, width: '100%' };
}

const fillStyle = isVertical
? { top: `${railFillXPosition}px`, height: `${railFillWidth}px`, width: '100%' }
: { left: `${railFillXPosition}px`, width: `${railFillWidth}px` };
return { left: `${railFillXPosition}px`, width: `${railFillWidth}px` };
})();

return (
<Slider ref={ref} className={cx(orientation === 'vertical' && classes.verticalOrientation)}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface SliderInternalProps {

export interface SliderViewProps extends SliderBaseProps, SliderInternalProps {
orientation: 'horizontal' | 'vertical';
reversed?: boolean;
size: string;
sliderAlign?: string;
railFillWidth: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { styled } from '@linaria/react';

import { classes, tokens } from '../../Slider.tokens';

export const StyledValue = styled.span<{ isLargeThumb?: boolean }>`
export const StyledValue = styled.span<{ isLargeThumb?: boolean; isPointerHidden?: boolean }>`
position: absolute;
z-index: 1;
top: var(${tokens.currentValueTopOffset});
text-align: center;
width: 100%;
margin-left: -0.125rem;
margin-left: ${({ isPointerHidden }) => (isPointerHidden ? 'calc(var(--thumb-size))' : 'calc(-0.125rem)')};
display: flex;
justify-content: center;
font-family: var(${tokens.valueFontFamily});
Expand All @@ -19,27 +19,31 @@ export const StyledValue = styled.span<{ isLargeThumb?: boolean }>`
line-height: var(${tokens.valueLineHeight});
`;

export const HandlerStyled = styled.div<{ isLarge?: boolean }>`
export const HandlerStyled = styled.div<{ isLarge?: boolean; isPointerHidden?: boolean }>`
--thumb-size: ${({ isLarge }) => (isLarge ? `var(${tokens.thumbSizeLarge})` : `var(${tokens.thumbSize})`)};
cursor: pointer;
position: absolute;
z-index: 1;
top: 0;
left: 0;
left: calc(var(--thumb-size) / -2 - 0.0625rem);
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
--thumb-size: ${({ isLarge }) => (isLarge ? `var(${tokens.thumbSizeLarge})` : `var(${tokens.thumbSize})`)};
&.${classes.verticalOrientation} {
right: 0;
left: 0;
top: calc(var(--thumb-size) / -2 - 0.0625rem);
bottom: auto;
margin-left: -0.0625rem;
align-items: flex-start;
justify-content: center;
${StyledValue} {
margin: 0;
margin: ${({ isPointerHidden }) => (isPointerHidden ? 'calc(var(--thumb-size) / 2 )' : 'calc(-0.125rem)')} 0
0;
top: 0;
bottom: 0;
right: 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef, forwardRef, KeyboardEvent } from 'react';
import React, { useRef, useState, forwardRef, KeyboardEvent } from 'react';
import Draggable, { DraggableEventHandler } from 'react-draggable';

import { cx } from '../../../../utils';
Expand All @@ -21,6 +21,8 @@ export const Handler = forwardRef<HTMLDivElement, HandlerProps>(
(
{
size,
visibility,
isHovered,
orientation,
stepSize,
onChangeCommitted,
Expand All @@ -42,6 +44,7 @@ export const Handler = forwardRef<HTMLDivElement, HandlerProps>(
ref,
) => {
const isVertical = orientation === 'vertical';
const [isDrag, setIsDrag] = useState(false);

const lastOnChangeValue = useRef<number>();
const [startClientOffset, endClientOffset] = getOffsets(ref, side, isVertical);
Expand Down Expand Up @@ -72,7 +75,13 @@ export const Handler = forwardRef<HTMLDivElement, HandlerProps>(
}
};

const onStart: DraggableEventHandler = () => {
setIsDrag(true);
};

const onStop: DraggableEventHandler = (_, data) => {
setIsDrag(false);

const newValue = getSliderThumbValue(isVertical ? data.y : data.x, stepSize, min, max);
onChangeCommitted && onChangeCommitted(newValue, data);
};
Expand Down Expand Up @@ -112,11 +121,17 @@ export const Handler = forwardRef<HTMLDivElement, HandlerProps>(
onChangeCommitted && onChangeCommitted(computedValue, data);
};

let isPointerHidden = (visibility === 'onHover' && !isHovered) || size === 'none';

if (isDrag) {
isPointerHidden = false;
}
return (
<Draggable
axis={isVertical ? 'y' : 'x'}
bounds={computedBounds}
grid={isVertical ? [1, stepSize] : [stepSize, 1]}
onStart={onStart}
onStop={onStop}
onDrag={onDrag}
position={dragPosition}
Expand All @@ -130,20 +145,26 @@ export const Handler = forwardRef<HTMLDivElement, HandlerProps>(
valuePlacement === 'left' && classes.valuePlacementLeft,
)}
isLarge={size === 'large'}
isPointerHidden={isPointerHidden}
onKeyDown={onKeyPress}
>
{size !== 'none' && (
<Thumb
tabIndex={tabIndex}
min={min}
max={max}
value={value}
disabled={disabled}
orientation={orientation}
{...rest}
/>
{(visibility === 'always' || (visibility === 'onHover' && (isHovered || isDrag))) &&
size !== 'none' && (
<Thumb
tabIndex={tabIndex}
min={min}
max={max}
value={value}
disabled={disabled}
orientation={orientation}
{...rest}
/>
)}
{showCurrentValueCondition && (
<StyledValue isPointerHidden={(visibility === 'onHover' && !isHovered) || size === 'none'}>
{value}
</StyledValue>
)}
{showCurrentValueCondition && <StyledValue>{value}</StyledValue>}
</HandlerStyled>
</Draggable>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface HandlerProps {
onChangeCommitted?(value: number, data: DraggableData): void;
side?: 'left' | 'right';
size?: 'small' | 'large' | 'none';
visibility?: 'always' | 'onHover';
isHovered?: boolean;
orientation: 'horizontal' | 'vertical';
bounds?: number[];
position?: number;
Expand Down
Loading

0 comments on commit 145c113

Please sign in to comment.