Looking to develop a swipeable card feature similar to Gmail using React JS (excluding React Native)?

Looking to replicate the swipe card functionality of Gmail in React Js,

After creating the UI and implementing swiping using UseGeature, I am facing an issue with smooth animation when hiding or showing buttons using UseEffect. There is a 20px movement before reaching the required width.

One approach I tried was using two layers - buttons on the bottom layer and the main card on the top layer. However, I now face a problem where I cannot click on the buttons after swiping, even when they are visible. This is because the top layer (card) has its own touch action that prevents touch propagation to the buttons.

I experimented with changing the Z-Index using UseEffect to enable button clicks, but this caused animation glitches.

Has anyone encountered a similar challenge and found a solution that they could share or suggest?

Thank you in advance. https://i.sstatic.net/pgtHc.png (this is not the actual UI)

Answer №1

Do you think this will be beneficial?

$.fn.extend({
    createBtn: function () {
        var elmWidth = $("li", $(this)).width(),
            listType = $(this).listview("option", "inset") ? true : false,
            btnWidth = elmWidth < 300 && listType ? "35%" : elmWidth > 300 && !listType ? "25%" : "20%";
        $("li", $(this)).each(function () {
            var text = $(this).html();
            $(this).html($("<div/>", {
                class: "wrapper"
            }).append($("<div/>", {
                class: "go"
            }).text("Save").width(btnWidth)).append($("<div/>", {
                class: "item"
            }).text(text)).append($("<div/>", {
                class: "del"
            }).text("Delete").width(btnWidth)).css({
                left: "-" + btnWidth
            }).on("swipeleft swiperight vclick tap", function (e) {

                $(this).revealBtn(e, btnWidth);
            }) /**/ );
        });
    },
    revealBtn: function (e, x) {
        var check = this.check(x),
            swipe = e.type;
        if (check == "closed") {
            swipe == "swiperight" ? this.open(e, x, "left") : swipe == "swipeleft" ? this.open(e, x, "right") : setTimeout(function () {
                this.close(e);
            }, 0);
            e.stopImmediatePropagation();
        }
        if (check == "right" || check == "left") {
            swipe == "swiperight" ? this.open(e, "left") : swipe == "swipeleft" ? this.open(e, x, "right") : setTimeout(function () {
                this.close(e);
            }, 0);
            e.stopImmediatePropagation();
        }
        if (check !== "closed" && e.isImmediatePropagationStopped() && (swipe == "vclick" || swipe == "tap")) {
            this.close(e);
        }
    },
    close: function (e) {
        var check = this.check();
        this.css({
            transform: "translateX(0)"
        });
    },
    open: function (e, x, dir) {
        var posX = dir == "left" ? x : "-" + x;
        $(this).css({
            transform: "translateX(" + posX + ")"
        });
    },
    check: function (x) {
        var matrix = this.css("transform").split(" "),
            posY = parseInt(matrix[matrix.length - 2], 10),
            btnW = (this.width() * parseInt(x) / 100) / 1.1;
        return isNaN(posY) ? "closed" : posY >= btnW ? "left" : posY <= "-" + btnW ? "right" : "closed";
    }
});

$(document).on("pagecreate", function () {
    $("ul").createBtn();
});
div[data-roler="header"] h1 {
  background: #f90 !important;
}
li {
    padding: 0 !important;
}
li .wrapper {
    display: block;
    height: 100%;
    width: auto;
    position: relative;
    -webkit-transition: -webkit-transform 300ms ease;
    -moz-transition: -moz-transform 300ms ease;
    transition: transform 300ms ease;
}
.wrapper .go, .wrapper .item, .wrapper .del {
    display: inline-block;
    padding: 0.9em;
    text-shadow: none;
    border-style: none;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.wrapper .item {
    width: 100%;
    height: 100%;
}
.wrapper .go, .wrapper .del {
    height: 100%;
    text-align:center;
    font-weight: bold;
    border-width: 1px 0;
    border-style: solid;
    border-color: #ddd;
}
.wrapper .go {
    background: #009925;
    border-color: #009925;
}
.wrapper .del {
    background: #F90101;
    border-color: #F90101;
}
<html>
  <head>
<meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
  </head>
  <body>
<div data-role="page">
    <div data-role="header" data-position="fixed">
         <h1>Test</h1>
    </div>
    <div role="main" class="ui-content">
        <ul data-role="listview">
            <li>Swipe me 1</li>
            <li>Swipe me 2</li>
            <li>Swipe me 3</li>
            <li>Swipe me 4</li>
            <li>Swipe me 5</li>
        </ul>
    </div>
    <div data-role="footer" data-position="fixed" data-theme="a" data-tap-toggle="false">
         <h1>Hallo</h1>

    </div>
</div>
    </body>
  </html>

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

TypeScript error: Cannot find property 'propertyName' in the 'Function' type

I encountered an issue with the TypeScript compiler when running the following code snippet. Interestingly, the generated JavaScript on https://www.typescriptlang.org/play/ produces the desired output without any errors. The specific error message I recei ...

Difficulty encountered when trying to update intricate model using Angular UI modal

My current project involves managing a model containing nested arrays that represent different sections of a floor plan. Each section contains an array of booth objects. To optimize user interaction, I've created a view that displays all the booths on ...

What is the best way to incorporate Blade code into a React component within a Blade view file?

Recently, I've been working on a Laravel view named homepage.blade.php, which includes the following code: <body> <div id=root></div> <script src="./js/app.js"></script> </body> In the app.js file: ...

Searching for the index of a nested array in jQuery using JSON

I am currently working on developing an image uploader using Codeigniter3 along with jQuery and Ajax. Problem: I am facing difficulty in understanding how to locate the index of the array received from the ajax response shown below. Here is the data retu ...

Is it possible for a conditional type in TypeScript to be based on its own value?

Is it possible to use this type in TypeScript? type Person = { who: string; } type Person = Person.who === "me" ? Person & Me : Person; ...

The browser has blocked access to XMLHttpRequest from a specific origin due to the absence of the 'Access-Control-Allow-Origin' header in the requested resource

After developing an Asp.Net Core 3.1 API and deploying it on the server through IIS, everything worked fine when sending GET/POST requests from Postman or a browser. However, I encountered an error with the following code: $.ajax({ type: 'GET' ...

Tips on how to align several divs within another div

I've been attempting to center multiple div blocks within another div or HTML document, but I haven't had any success with the methods I've found on StOv. Here's an image of what I'm aiming for: https://i.stack.imgur.com/DB7uQ.jp ...

Dealing with a Node and Express server can be tricky, especially when trying to proxy a POST request along with parameters. You might encounter the error

I am trying to forward all requests made to /api/ from my local node server to a remote server, while also adding some authentication parameters to them. Everything works smoothly for GET requests with query parameters and POST requests without specifying ...

Tips for resizing the width automatically within a container?

I am facing an issue with a container that contains 3 DIVS: left sidebar, main content, and a right sidebar. I have made the main content responsive by setting the width to width:calc(100% - 400px); (where 400px is the combined width of the sidebars). Howe ...

The error "Cannot access property of undefined during an Ajax POST request" indicates

I am currently facing an issue with uploading a music file using AJAX to save the data into my MongoDB when I click the 'upload' button. Unfortunately, I keep receiving an error stating that "fieldname is undefined". It seems like there might be ...

Problem with implementing swipeable tabs using Material-UI in React

I'm experiencing an issue in my application with the react swipeable tabs from material-ui. I followed all the installation steps recommended in the documentation. Currently, I am encountering the error shown in the screenshot below. Could there be a ...

PHP is mistakenly displayed on the incorrect webpage

Lately, I've been immersed in a website project. I have a website.php file that contains all the HTML code, a function.php file, and a saveArray.js file. Within website.php, I've included a HTML table with a button at the bottom. When this button ...

What is the best location to manage errors within a sequelize ORM query?

I am working with the Sequelize ORM within a Node/Express environment. My database has two tables: one for Users and another for Items. The Item table includes a foreign key that is linked to the UserId in the User table. Whenever I attempt to create an ...

Making a POST request using axios in a MERNStack application

After successfully using the express router to add articles with Postman, I encountered an issue when trying to send article information through Axios to MongoDB. Despite no errors appearing in the console, there was a message stating "SharedArrayBuffer ...

Access both the main collection and its sub-collection in Firebase

I have been attempting to retrieve all data related to a collection and its subCollections within my Firestore database. The structure of the database is as follows: collection|->document|->subCollection|->document|-... |->field ...

Can you target an 'input' field that is within a component conditionally rendered using 'v-if'?

Imagine this vue.js template code: <div v-if="y===0"> <input ref="textbox">{{textbox}}</input> </div> In the scenario where y is data retrieved asynchronously, Is there a way to direct focus to the 'input' element onc ...

The RangeError occurs when attempting to deploy to Heroku due to exceeding the maximum call stack size at Array.map in an anonymous function

While attempting to deploy a MERN stack application to Heroku, I encountered an error in the Heroku CLI. RangeError: /tmp/build_c861a30c/frontend/node_modules/@reduxjs/toolkit/dist/redux-toolkit.esm.js: Maximum call stack size exceeded at Array. ...

What is the best way to create an `isHook` function in my code?

Is there a way to determine if a function passed is a React Hook? isHook(useState); // returns true isHook(() => {}); // returns false; I am looking for a method to distinguish whether a function attached to an object property is a hook or not. In cas ...

Transmitting state to infinitely nested component in React/Redux

I'm currently facing an issue with a component that has children of the same type as itself in React with Redux. Although I can render the children, they are unable to access their own slice of state. export class Material extends React.Component { ...

Create an illustration of a canvas interacting with a database image source, but failing to display local images

When attempting to load an image onto a canvas, I encountered an issue. My code works without any errors when I use image.src="https://somelink", but throws a GET error when I try to import with image.src="../public/vercel.svg. Below is my c ...