Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slider "active area" is offset from where the actual element is #470

Open
Torniojaws opened this issue Dec 23, 2022 · 14 comments
Open

Slider "active area" is offset from where the actual element is #470

Torniojaws opened this issue Dec 23, 2022 · 14 comments
Labels
bug report Something isn't working

Comments

@Torniojaws
Copy link

Environment

System:
    OS: macOS 12.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 680.34 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 14.17.0 - ~/.nvm/versions/node/v14.17.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v14.17.0/bin/yarn
    npm: 6.14.13 - ~/.nvm/versions/node/v14.17.0/bin/npm
    Watchman: Not Found
  Managers:
    CocoaPods: Not Found
  SDKs:
    iOS SDK:
      Platforms: DriverKit 22.1, iOS 16.1, macOS 13.0, tvOS 16.1, watchOS 9.1
    Android SDK: Not Found
  IDEs:
    Android Studio: 2021.2 AI-212.5712.43.2112.8512546
    Xcode: 14.1/14B47b - /usr/bin/xcodebuild
  Languages:
    Java: javac 19 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: Not Found
    react-native: Not Found
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

(Possibly) relevant deps from package.json:

    "@react-native-community/slider": "4.2.4",
    "@react-navigation/material-top-tabs": "6.2.1",
    "@react-navigation/native": "6.0.10",
    "@react-navigation/native-stack": "6.6.2",
    "expo": "~44.0.2",
    "expo-font": "~10.0.4",
    "expo-splash-screen": "~0.14.1",
    "expo-status-bar": "~1.2.0",
    "jsc-android": "^250230.2.1",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-calendars": "1.1289.0",
    "react-native-collapsible": "1.6.0",
    "react-native-pager-view": "5.4.9",
    "react-native-safe-area-context": "3.3.2",
    "react-native-screens": "~3.10.1",
    "react-native-tab-view": "3.1.1",
    "react-native-web": "0.17.1"

Description

I have a Slider component that works perfectly fine on browser simulated mobile phone environment (Chrome -> responsive "iPhone 6/7/8 Plus" preset). But when I use the slider on a bigger screen (Chrome -> responsive "iPad Pro" preset), the active range (where the slider starts moving with mouse drag) is far to the left from where the actual slider element is.

Let's say, the slider element is between width 750px and 900px:

  1. When I simply click on the slider, it goes automatically to maximumValue
  2. If I click & hold the slider, and then pull to the left side of the screen, nothing happens to the slider. It does not move.
  3. But when I reach the left edge of the screen (about 100px), then the slider starts to move with the mouse drag.

Here's a video. The first part is the "click makes it max value", and then comes the slider offset:

Screen.Recording.2022-12-23.at.15.02.25.mov

Reproducible Demo

const styles = StyleSheet.create({
  sliderBox: {
    flexDirection: 'row',
  },
});

interface Params {
  min: number;
  max: number;
  initialValue: number;
  bidToEdit: Bid;
  setter: Function; // This just passes the value to the parent, does not affect incoming params
}

export const CustomSlider = ({ min, max, initialValue, bidToEdit, setter }: Params) => {
  const [value, setValue] = useState<number>(initialValue);

  const sliderUpdated = (newValue: number) => {
    console.warn('Slider update to', newValue);
    setValue(newValue);
    setter(newValue);
  };

  return (
    <View style={styles.sliderBox}>
      <Slider
        value={value}
        step={1}
        onValueChange={sliderUpdated}
        minimumValue={min}
        maximumValue={max}
        minimumTrackTintColor={Colors.blue900Default}
        maximumTrackTintColor={Colors.blue50}
        thumbTintColor={Colors.blue900Default}
      />
      <SliderPoints value={value} updatePoints={sliderUpdated} min={min} max={max} />
    </View>
  );
};

I've also tried setting a maxWidth for the containing <View> but it doesn't change the behaviour.

I have also tried using onSlidingComplete and onSlidingStart, but the behaviour is still the same.

@Torniojaws Torniojaws added the bug report Something isn't working label Dec 23, 2022
@BartoszKlonowski
Copy link
Member

Hello @Torniojaws!
Thanks for a detailed report. One thing I have in mind before I start analysing this: Could you check if the issue still occur if you set the height and especially width to the style prop of Slider itself as well, instead of trimming it with the container View styles only?

@BartoszKlonowski BartoszKlonowski added this to To be analyzed in Slider-Board via automation Dec 27, 2022
@mathias-berg
Copy link

I also had this problem when upgrading from version 3 to version 4.
I have a solution that solves this that I will make a PR for.

@Torniojaws, when this happens, could you please try to change the width of the browser. Will it work after that (without reloading)?

@qqoo6789
Copy link

qqoo6789 commented Jan 11, 2023

@mathias-berg I have the same problem,the slider offset problem can be solved by changing the browser width.

But there is no reason for users to change the browser size. Secondly, our web application will be nested by iframe, so the problem will still not be solved.

@qqoo6789
Copy link

qqoo6789 commented Jan 11, 2023

@BartoszKlonowski

Not using slider style to change the width and height, and using for external Settings, this issue still exists but has not been resolved.

@mathias-berg
Copy link

@mathias-berg I have the same problem,the slider offset problem can be solved by changing the browser width.

But there is no reason for users to change the browser size. Secondly, our web application will be nested by iframe, so the problem will still not be solved.

Sadly, the fix that I was working didn't fix this. Still had the problem occasionally, will look into another solution.

@Torniojaws
Copy link
Author

@BartoszKlonowski
I tried setting a width to <Slider> itself, but seems it only "resized" the left edge offset area where moving changes the slider:

Screen.Recording.2023-01-13.at.17.28.51.mov

@mathias-berg
Actually yes, when I resize the browser window, it fixes the slider behaviour. Quite interesting.

@mathias-berg
Copy link

mathias-berg commented Jan 13, 2023

The problem is because at onLayout the containerRef is sometimes undefined and therefore the position is not saved and defaults to 0. But when changing the size of the window there is a listener that updated the new value and the position is saved correctly.

This is the the part of the code that is causing this since containerRef.current is not a truthy value all the times.
if ((containerRef as RefObject<View>).current) { updateContainerPositionX(); }

@gilador
Copy link

gilador commented Feb 18, 2023

I find this bug making this library, unfortunately, useless

UPDATE: upgrading to expo 46->47 has fixed the issue

@mathias-berg
Copy link

I'm on SDK 47 and it still exists for me

@YoussefHenna
Copy link

A workaround I found is to force onLayout to be called a second time by changing the thumbStyle prop and then reverting back.

const [tempThumbStyle, setTempThumbStyle] = React.useState<ViewStyle>({
    width: 0,
    height: 0,
  });

  React.useEffect(() => {
    setTempThumbStyle({ width: undefined, height: undefined });
  }, []);

And

<Slider
...
//@ts-ignore Not registered in types
thumbStyle={Platform.OS === "web" ? tempThumbStyle : undefined}
/>

Not pretty, but does the trick for now.

@WKampel
Copy link

WKampel commented Nov 4, 2023

Still broken in latest version of expo (49.0.10)

@trentcowden
Copy link

Still occurring for me on Expo sdk 50.

@trentcowden
Copy link

@YoussefHenna's workaround worked for me.

@raqso
Copy link

raqso commented May 29, 2024

A workaround I found is to force onLayout to be called a second time by changing the thumbStyle prop and then reverting back.

const [tempThumbStyle, setTempThumbStyle] = React.useState<ViewStyle>({
    width: 0,
    height: 0,
  });

  React.useEffect(() => {
    setTempThumbStyle({ width: undefined, height: undefined });
  }, []);

And

<Slider
...
//@ts-ignore Not registered in types
thumbStyle={Platform.OS === "web" ? tempThumbStyle : undefined}
/>

Not pretty, but does the trick for now.

If someone looking for a solution and above don't work for you - try to use regular style prop instead thumbStyle. Did work for me.

import { useState, useEffect, ComponentProps } from 'react';
import { Platform, ViewStyle } from 'react-native';
import SliderLib from '@react-native-community/slider';

type Props = ComponentProps<typeof SliderLib>;
export const Slider = ({ style, ...props }: Props) => {
	// https://github.com/callstack/react-native-slider/issues/470#issuecomment-1777525861
	const [tempStyle, setTempStyle] = useState<ViewStyle>({
		width: 0,
		height: 0,
	});

	useEffect(() => {
		setTempStyle({ width: undefined, height: undefined });
	}, []);

	return <SliderLib style={[Platform.OS === 'web' ? tempStyle : undefined, style]} {...props} />;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Something isn't working
Projects
Slider-Board
  
To be analyzed
Development

No branches or pull requests

9 participants