Interactive Typescript slider with drag functionality

Seeking assistance in developing a draggable slider using TypeScript. I have managed to retrieve the client and scroll positions, but I am struggling to change the ref scrollLeft position. There are no errors thrown; however, the ref's scrollLeft property remains unchanged.

I attempted logging the ref property that provides the div ref, yet the scrollLeft position consistently shows as 0.

import React, { useRef, useState } from "react";
import Nav from "./Nav";

const Services: React.FC = () => {
    const ref = useRef<HTMLDivElement | null>(null);
    const [state, setState] = useState({
        isDown: false,
        clientX: 0,
        scrollX: 0,
    });
    const onMouseDown = (e: React.MouseEvent<HTMLDivElement>): void => {
        e.persist();
        setState({
            ...state, isDown: true,
            clientX: e.clientX,
        });
    };

    const onMouseUp = () => {
        setState({ ...state, isDown: false });
    };
    const onMouseLeave = () => {
        setState({ ...state, isDown: false });
    };

    const onMouseMove = (e: React.MouseEvent<HTMLDivElement>): void => {
        e.persist();
        if (!state.isDown) { return; }
        const { clientX, scrollX } = state;
        if (ref.current) {
            // console.log(ref.current.scrollLeft);
            ref.current.scrollLeft = scrollX + e.clientX - clientX;
            console.log(ref.current.scrollLeft, scrollX + e.clientX - clientX);
            // state.scrollX = scrollX + e.clientX - clientX;
            // state.clientX = e.clientX;
     }
    };
    return (
        <main>
            <Nav/>
            <div id="content">
                <div className="draggable-slider" ref={ref}
                    onMouseDown={onMouseDown}
                    onMouseUp={onMouseUp}
                    onMouseLeave={onMouseLeave}
                    onMouseMove={onMouseMove}>
                   <div className="slide">
                       <h3>.01</h3>
                       <h3>Basic</h3>
                       <div className="slide-image">1</div>
                   </div>
                   <div className="slide">
                        <h3>.02</h3>
                        <h3>Basic</h3>
                       <div className="slide-image">2</div>
                   </div>
                   <div className="slide">
                        <h3>.03</h3>
                        <h3>Basic</h3>
                       <div className="slide-image">3</div>
                   </div>
                   <div className="slide">
                        <h3>.04</h3>
                        <h3>Basic</h3>
                       <div className="slide-image">4</div>
                   </div>
               </div>
            </div>
        </main>
    );
};

export default Services;

The CSS

.draggable-slider {
    position: relative;
    display: grid;
    padding: 1rem;
    width: 100%;
    grid-template-columns: repeat(4, 400px);
    grid-column-gap: 3em;
    top: 35vh;
    user-select: none;
    background-color: red;

    .slide {
      padding: 10px;
      line-height: 1;
    //   cursor: grab;

    // &.is-grabbing{
    //   cursor: grabbing;
    //    }



Desiring the ability to establish the draggable slide by altering the div scrollLeft position.

Answer №1

Your reasoning is not quite accurate in this instance:

ref.current.scrollLeft = scrollX + e.clientX - clientX;
. When you log the result of this calculation, you'll observe that it yields a negative number.

As per the MDN documentation on Element.scrollLeft:

If specified as a value less than 0 (greater than 0 for right-to-left elements), scrollLeft is set to 0.

This clarifies why the value seems to remain at 0 consistently. You can see this behavior demonstrated in a CodeSandbox example.

Hopefully this information helps you make progress! Best of luck!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to ensure that my website's elements adjust automatically to different screen sizes?

Recently, I encountered a small snippet of HTML code with the main focus being an h2 element. #top-warning{ justify-content: center !important; display: flex; width: 100%; margin-top: 5vw; letter-spacing: 3px; font-family: "Penguin Regular ...

How to dynamically delete React Router Link components after they have been clicked on?

When using React Router, how do I remove the div that contains a Link component or the Link component itself when it is clicked on and the routing is complete? For instance, consider an app structured in the following way: ==Header== ==Link1 Link2== Onc ...

Tips for uploading the IDENTICAL file in angular4

After successfully uploading a file, I encountered an issue where the system does not allow me to upload the same file twice. Here is the code snippet related to the problem: <input type="file" (change)="onFileChange($event)" name="fileUploaded" value ...

Tips for displaying dynamic images using the combination of the base URL and file name in an *ngFor loop

I have a base URL which is http://www.example.com, and the file names are coming from an API stored in the dataSource array as shown below: [ { "bid": "2", "bnam": "ChickenChilli", "adds": "nsnnsnw, nnsnsnsn", "pdap": " ...

Tips on ensuring a div stays on the same line

I am facing an issue with a div containing two inner divs, which is currently structured as follows: https://i.sstatic.net/jy8s6.png However, when the second inner div has more content, it appears like this: https://i.sstatic.net/ezvyU.png Is there a w ...

Mastering the Art of Absolute Positioning in HTML Tables' Header Row

I have a table with 80 rows. How can I make the first row fixed? I attempted to add position: fixed; to the but unfortunately, it didn't work. Is there a way to achieve this using CSS or jQuery? <table> <thead> <tr> <td sty ...

Issues with Angular2 http.get() returning 404 errors consistently

I'm encountering an issue while attempting to load dummy JSON data from a file using angular2 http.get method. It appears that the method is unable to retrieve the data, consistently returning a 404 status code for resource not available. Below is the ...

Custom stylesheet for individual users?

On my website, users can pick a template for their webpage. After selecting a template, I would like them to have the ability to customize certain styles like the font color. Is there a way to achieve this? I was thinking about saving the user's cus ...

When you adjust the size of your web browser, the text may become distorted in HTML and CSS

My website has a problem with text resizing when the browser window is made smaller. The text gets squashed in the middle and creates more lines than needed. Here is my code: Entire Document HTML: http://pastebin.com/kj1jvTjv CSS: http://pastebin.com/A1C ...

CompositeAPI: Referencing HTML Object Template - Error TS2339 and TS2533 when using .value to access Proxy Object

Having trouble referencing an element in VueJS 3 CompositeAPI. In my current implementation, it looks like this: <div ref="myIdentifier"></div> setup() { const myIdentifier = ref(null); onMounted(() => { console.log(myIden ...

How come the "domino effect" from Material-UI is not apparent when incorporated into a Popup within a Leaflet map?

Trying to insert a Material-UI Button into a Popup within the Leaflet library has presented a challenge. While everything works perfectly outside of the Popup, with each button triggering a ripple effect upon click, placing the same code inside a marker po ...

The JSON file overwrites entire objects instead of targeting individual ones

Is there a way to update just one specific object in a JSON file without affecting the rest? I've implemented a put request on the front-end using axios to send data to the back-end for processing. However, the current functionality replaces all obje ...

Pressing the button will allow you to select and copy the text within the

I am looking to incorporate a mock-chat feature into my website. The concept is to type something on the website, then click a button next to it which will move the text to a frame above. I attempted this using a textarea and even found a code for selectin ...

Button placement that feels out of place

I'm looking to style an input-group with a form input and submit button using Bootstrap 5. Here's my current code: .card { margin: auto; width: 50%; padding: 10px; opacity: 0.9!important; top: 250px; } <div class="card-header"> ...

Persistent banner designed to accompany blog posts

I've been attempting to insert a banner ad that runs along the left side of my blog post. Unfortunately, all my efforts so far have caused it to display above the content, pushing the blog post down the page. You can view the live link here. Here i ...

The PaymentElement feature within Stripe is specifically designed to display the card option exclusively

Currently, I am in the process of setting up subscriptions using the new PaymentElement. The documentation that I am following can be found here: https://stripe.com/docs/billing/subscriptions/build-subscription?ui=elements#display-payment-method In my sub ...

Require verification in MDB entries

I am currently using the MDB package to create a login page that requires validation. Here is the code I have written: <MDBValidation className='row g-3' isValidated> <MDBValidationItem > <MDBInput ...

Adding a standard JavaScript file to a React application

Seeking guidance on how to incorporate this plugin into my React project. It appears to be set up using script tags in a traditional manner. Can anyone advise on the best approach for this? Here is the structure of my project hierarchy: . ├── app ...

The art of arranging React components

I'm struggling to organize my react components properly and I'm having difficulty with CSS Flexbox. Here are the 3 react components: function App() { return ( <> <div className = "header"> <h1>Connect ...

Trouble with invoking a function within a function in Ionic2/Angular2

Currently, I am using the Cordova Facebook Plugin to retrieve user information such as name and email, which is functioning correctly. My next step is to insert this data into my own database. Testing the code for posting to the database by creating a func ...