Giter Club home page Giter Club logo

react-swipeable-list's Introduction

react-swipeable-list's People

Contributors

allcontributors[bot] avatar arondeparon avatar harrisgca avatar marekrozmus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-swipeable-list's Issues

Action Icon not persisting

Hi, I have your component installed and mostly working. Thank you for making available.

Something I can't figure out: How do you make the action content persist on the screen? I can swipe, and see the action content come into view, but it does not stay in view like in samples. It just slides back out of view when released.

What am I doing wrong? My code is very similar to your usage example in the Readme. Very simple, just text.

Thanks..

Several actions open if opened after deletion

If I open a swipe after deleting a swipeItem using a destructive callback, then when I open the swipe next to it, several actions open, see video.
I think the problem is in #38 since the ID is tied to the index

1695219198.7310581.mp4

Delay on LeadingAction

I want to make a little icon animation before the Swipe back onClick but it disappears before and the destructiveCallbackDelay isn't working! Any workaround for this problem? thanks

Warning: React does not recognize the X prop on a DOM element

Hello
I'm getting this warning:
"Warning: React does not recognize the X prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase actiondelay instead. If you accidentally passed it from a parent component, remove it from the DOM element."

for:
actionDelay, destructiveCallbackDelay, fullSwipe, listType, scrollStartThreshold and swipeStartThreshold

Allow clickthrough if swipe hasn't started yet

Is your feature request related to a problem? Please describe.
For my use case I need a swipeable list that is also clickable, which the library doesn't support currently.
I believe this could be a nice addition.

Describe the solution you'd like
Allow clickthrough when the swipe threshold hasn't been hit.
I would like into this myself but don't really have the time currently.

Describe alternatives you've considered
None

SwipeableListItem onClick action triggered, when element swiped

Swipe action triggers onClick event

Steps to reproduce the behavior:

  1. Swipe trailing actions
  2. 'SwipeableListItem' element onClick triggered

Expected behavior:
onClick should work apart from swipe actions

Desktop (please complete the following information):

  • OS: iOS
  • Browser Safari

Code:

    const trailingActions = (onDelete) => (
      <TrailingActions>
        <SwipeAction onClick={onDelete} destructive={true}>
          <ActionContent style={{ backgroundColor: 'red' }}>
            <DeleteOutlined style={{ fontSize: 18 }} />
          </ActionContent>
        </SwipeAction>
      </TrailingActions>
    );

    <SwipeableList fullSwipe={false} type={ListType.IOS}>
      {!!items.length &&
        items?.map((item) => (
          <SwipeableListItem
            leadingActions={null}
            trailingActions={trailingActions(() => removeItem(item))}
            key={item?.id}
            onClick={(e) => {
              console.log('click'); // THIS CODE SHOULD NOT WORK ON SWIPE BUT IT DOES.
            }}
          >
            <Card style={{ borderRadius: 0, width: '100%' }}>
              <Row>
                <Col span={1}>1</Col>
                <Col span={20}>
                  <p>{item?.name}</p>
                </Col>
                <Col span={3}>
                  <p>{item?.totalCost}</p>
                </Col>
              </Row>
            </Card>
          </SwipeableListItem>
        ))}
    </SwipeableList>

React does not recognize the x...

Hello, great lib!
I'm getting this warning:
"Warning: React does not recognize the X prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase actiondelay instead. If you accidentally passed it from a parent component, remove it from the DOM element."

for:
actionDelay, destructiveCallbackDelay, fullSwipe, listType, scrollStartThreshold and swipeStartThreshold

Using React 18.2.0
I did not get these when using React 17.

Thanks in advance and keep up the good work!

_this.trailingFullSwipeAction is not a function

Describe the bug
I'm trying to implement a configurable Swipeable List.
But whenever I try to full swipe left I got this error:

Unhandled Runtime Error
TypeError: _this.trailingFullSwipeAction is not a function

Call Stack
SwipeableListItem.eval [as handleDragEnd]
node_modules/react-swipeable-list/dist/react-swipeable-list.umd.js (615:0)
eval
node_modules/react-swipeable-list/dist/react-swipeable-list.umd.js (422:0)

I have the same implementation for swipe right and the error does not occur.

And the destructable does not run properly.

How to Reproduce
Props:

  const actionLeading0 = (id) => () => {
    console.log('Leading0',id)
  };
  const actionTrailing0 = (id) => () => {
    console.log('Trailing0',id)
  };
  const actionClick = (id) => () => {
    const place = places.find(place => place.id === id);
    console.log('Click',id, place);
    navigate({pathname: '/places/' + place?.name, search:`?id=${id}`});
  };
  const actionSwipeStart = (id)=>{
    console.log('SwipeStart',id)
  };
  const actionSwipeProgress = (progress, id)=>{
    console.log('SwipeProgress',progress ,id)
  };
  const actionSwipeEnd = (id)=>{
    console.log('SwipeEnd' ,id)
  };
  const stylesLeading = [
    { backgroundColor: colors.accepted, color: "black" },
    { backgroundColor: colors.rejected, color: "black" }
  ]

  const stylesTrailing = [
    { backgroundColor: colors.rejected, color: "black" },
    { backgroundColor: colors.deleted, color: "black" }
  ]


fullSwipe={true}
actionLeading={[actionLeading0]}
actionTrailing={[actionTrailing0]}
actionClick={actionClick}
actionSwipeStart={actionSwipeStart}
actionSwipeProgress={actionSwipeProgress}
actionSwipeEnd={actionSwipeEnd}
stylesLeading={stylesLeading}
labelsLeading={['Edit']}
destructiveLeading={[undefined]}
stylesTrailing={stylesTrailing}
labelsTrailing={['Delete']}
destructiveTrailing={[true]}

Actions:

const actions = ({id, name}) => {
    // 'Leading'|'actionTrailing'
    const actionName = 'action'+ name ;
    const labelName = 'labels'+ name ;
    const styleName = 'styles'+ name ;
    const destructiveName = 'destructive'+ name ;

    const actionElements: ReactElement<any, any>[] =[];
    for (let index = 0; index < props?.[`${actionName}`].length; index++) {
      const action = props?.[`${actionName}`]?.[index];
      const destructive: boolean = props?.[`${destructiveName}`]?.[index];
      const label = props?.[`${labelName}`]?.[index];
      const style = props?.[`${styleName}`]?.[index];

      if(action !== undefined) {
        const element = destructive
        ? (
          <SwipeAction
            destructive={destructive}
            onClick={action(id, props.delete)}>
            <ActionContent
              style={style}
            >
              {label}
            </ActionContent>
          </SwipeAction>
        ) : (
          <SwipeAction
            onClick={action(id, props.delete)}>
            <ActionContent
              style={style}
            >
              {label}
            </ActionContent>
          </SwipeAction>
        );
        actionElements.push(element);
      }
    }
    if(actionElements.length === 0) {
      return undefined;
    }
    const actions = (<LeadingActions>
      {actionElements}
    </LeadingActions>);
    return actions;
  };

SwipeableListItem:

<SwipeableListItem
    key={element?.id}
    leadingActions={actions({id: element?.id, name: 'Leading'})}
    trailingActions={actions({id: element?.id, name: 'Trailing'})}
    onSwipeEnd={()=>{
      if(props.actionSwipeEnd !== undefined)
      return props?.actionSwipeEnd(element?.id, props.delete);
    }}
    onSwipeProgress={(progress)=>{
      if(props.actionSwipeProgress !== undefined)
        return props?.actionSwipeProgress(progress, element?.id, props.delete);
    }}
    onSwipeStart={()=>{
      if(props.actionSwipeStart !== undefined)
        return props?.actionSwipeStart(element?.id, props.delete);
    }}
    onClick={props?.actionClick?.(element?.id, props.delete)}
  >
    <Item
      theme={props.theme}
      element={element}
      delete={handleDelete}
      quantity={
        quantities !== undefined && index !== undefined
          ? quantities[index]
          : undefined
      }
    >
      {children}
    </Item>
  </SwipeableListItem>

Desktop:

  • OS: OSX 12.3.1 M1
  • Browser: chrome
  • Version: 100.0.4896.88

How to programmatically swipe any list item to reveal the trailing actions

Hi,

Thank you for making this library with many swipe options! A very useful thing for the web 💯. I have this problem integrating this library into my app because I'm not able to do this one thing which is critical for UX perspective.

Is your feature request related to a problem? Please describe.

I'm working on an app where I want to show that the list is swipeable to new users so they know they can swipe an item to perform operations. I have a tooltip with animation which should play along with the automatic swipe transition.

Describe the solution you'd like

For the first-time users, the first item in the list should automatically(programmatically) swipe when the page loads and the tooltip animation starts playing. When the user taps anywhere on the screen the item should go back to its original state, along with hiding the tooltip and stopping its animation.

Tooltip and animation are taken care of, just this part is giving me hard times.

Describe alternatives you've considered

We have a custom solution for swiping the lists and animation in place, but it's not very interactive and users are having a hard time swiping the items.

Is it possible to use button list item inside SwipeableListItem?

Hello, thank you for this component!

I wonder if it is possible to use the button list item inside SwipeableListItem? So that I have swipe functionality as well as the possibility to click on the list item and e.g. open a new page. I have experimented differently with this and have not found the possibility to make this ending up with onClick button callback triggered as soon as swipe is performed.

Compatibility issue with newer Chromium

I get a lot of:

[Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952

in console when using your library in a toy project.

This is the line that triggers it:
this.listElement.addEventListener('touchstart', this.handleDragStartTouch);

Sorry, I have no clue about why this happens or whether that's not a problem (I see that you do add passive: true for touchmove event), I'm a backend guy mostly.

Does not work with react-awesome-dnd

Describe the bug
I'm trying to create a lit with react-swipeable-list and react-awesome-dnd I'm under the impression both should play nice together, but when I swipe to see the action, the action do not remain, the actions colpast again. If I remove react-awesome-dnd it works.

 <DragDropContext onDragEnd={onDragEnd(items, uid)}>
      <Droppable droppableId="droppable">
        {(provided1, snapshot) => (
          <div ref={provided1.innerRef} {...provided1.droppableProps} style={getListStyle(snapshot.isDraggingOver)}>
            <SwipeableList
              fullSwipe={false} type={Type.IOS}
            >
              {items.map((timer, index) => (
                <Draggable key={timer.id} draggableId={timer.id} index={index}>
                  {(provided2, snapshot) => (
                    <div
                      ref={provided2.innerRef}
                      {...provided2.draggableProps}
                      style={getItemStyle(snapshot.isDragging, provided2.draggableProps.style)}
                    >
                      <SwipeableListItem trailingActions={trailingActions(theme, timer, handleEditItem)}>
                        <Stack direction='row'>
                          <div {...provided2.dragHandleProps} style={{ alignSelf: 'center' }}>
                            <DragIndicatorIcon sx={{ mr: 1 }} htmlColor='gray' />
                          </div>
                          <Box sx={{ mt: 1, ml: 0, mr: 0 }}>
                            <Typography
                              variant='subtitle1'
                              fontWeight='bold'
                              alignSelf='start'
                              textTransform='capitalize'
                              textAlign='left'
                            >
                              {timer.title}
                            </Typography>
                            <TimerItemContent timer={timer} />
                          </Box>
                        </Stack>
                      </SwipeableListItem>
                    </div>
                  )}
                </Draggable>
              ))}
            </SwipeableList>
          </div>
        )}
      </Droppable>
    </DragDropContext>

Expected behavior
When I swipe I would expect the actions to remain so I can touch any of them

Desktop (please complete the following information):

  • chrome

Don't work in localhost with IOS twoaction button but work in codesandbox

I am using react-swipeable-list with type IOS two action button where in example it show when we swipe from left side and release it, It hold and show two buttons but in my case when i swipe from left side and after releasing it, It just go back to it's original position without showing actions button.

I attach the behaviour in gif format
issue video

But the same code work fine in codesandbox as you can see in below attach gif
codesandbox

Don't know what is the actual issue. I try it on safari, chrome and firefox in any of these it is not working.

Link to the code in sandbox

onSwipeStart only called once per element

Describe the bug
When using a trailing and leading action on a single element, onSwipeStart will only be called once.

To Reproduce
Steps to reproduce the behavior:

  1. Partially swipe right.
  2. Observe that onSwipeStart will trigger
  3. End swipe.
  4. Partially swipe left.
  5. Oberse that onSwipeStart will NOT trigger.

Expected behavior
onSwipeStart should trigger every time a new sequence is started.

Note: it does work when swiping on another SwipableListItem and afterwards returning to the original element.

Wrong counting for React.Children in TrailingActions

Describe the bug
In some cases Full Swipe with ≤2 children cases an error:

_this.trailingFullSwipeAction is not a function
TypeError: _this.trailingFullSwipeAction is not a function
    at SwipeableListItem.eval [as handleDragEnd] (webpack://react-swipeable-list-example/../src/SwipeableListItem.js?:328:19)
    at eval (webpack://react-swipeable-list-example/../src/SwipeableListItem.js?:174:13)

To Reproduce
Create a list of TrailingActions with 'null' as the last child:

<TrailingActions>
  <SwipeAction onClick={handleReject(id)}>
   ...
  </SwipeAction>
  <SwipeAction destructive={true} onClick={handleDelete(id)}>
   ...
  </SwipeAction>
  {null}
</TrailingActions>

Expected behavior
No error for cases if some of TrailingActions's children is not valid React element.

Desktop (please complete the following information):

  • OS: Android, iOS, mac
  • Browser: chrome
  • Version: latest

Additional context
How to fix: count valid react children before maping:

src/TrailingActions.js:
---
if (Array.isArray(children)) {

    let lastValidChildIndex = 0;

    React.Children.forEach(children, (child, index) => {
        if (React.isValidElement(child)) {
            lastValidChildIndex = index;
        }
    });

    return React.Children.map(children, (child, index) => {
      if (!React.isValidElement(child)) {
        return child;
      }
      return React.cloneElement(child, {
        main: index === lastValidChildIndex,
        trailing: true,
      });
    });
  }

Clarify relationship with @sandstreamdev/react-swipeable-list

I'd appreciate it if the README of this repo could clarify the relationship between this and https://github.com/sandstreamdev/react-swipeable-list/

When I first found this repo, it had the features I wanted over the sandstreamdev version. Given the similarities of the README and the repo name, it was hard to tell the two repos apart. I didn't know which one was the original and which was the fork, if both projects are maintained, and which one I might want to use.

After looking at the history, this appears to be a fork. Given the very similar naming, I'd like to understand why you published this fork and the main differences from the sandstreamdev version. For example, is the sandstreamdev version no longer being maintained? This has more features, but do you intend to maintain alignment with bugfixes in standstreamdev, or is this a totally divergent fork?

Provide a way to click / touch an opened item, toggle all other items to close, including itself

Hi there,

1, In many cases, users are only allowed to select actions for a single item at a time. This prevents multiple items from showing actions simultaneously. (Should be closed automatically first one if user tries to open another one)

2, Asking the user to swipe to close an action can be a poor user experience. (Also allowing close by clicking)

Is there any way to improve these?

trailingFullSwipeAction error every time I attempt to trigger a trailing swipe

Describe the bug
I have implemented the react swipeable list component within a comments list on a basic react web application I am building, each time i attempt to swipe right on a comment to delete it, on my localhost I trigger an uncaught runtime error, this is attached below: react-swipeable-list.umd.js:672 Uncaught TypeError: _this.trailingFullSwipeAction is not a function
at SwipeableListItem.handleDragEnd (react-swipeable-list.umd.js:672:1)
at HTMLDivElement. (react-swipeable-list.umd.js:481:1)

To Reproduce
Here is the code of the implementation:

const trailingActions = () => (
		<TrailingActions>
		  <SwipeAction
			destructive={true}
			onClick={() => console.info("swipe action triggered")}
		  >
			Delete
		  </SwipeAction>
		</TrailingActions>
	  );


		const HandleDeleteComment = (comment: string) => {
		console.log("deleting comment"); 
		};  
<div id="comments" >
		<SwipeableList threshold={0.25}  >
  {comments.map((item, index) => (
			<SwipeableListItem
			key={index}
			trailingActions={
				item.user === me.name ? (
				<TrailingActions>
					<div className="swipeActionDelete">
					<SwipeAction
						destructive={true}
						onClick={() => HandleDeleteComment(item.comment)}
					>
						Delete
					</SwipeAction>
					</div>
				</TrailingActions>
				) : null
			}
			>
			<ArtworkComment comment={item} />
			</SwipeableListItem>
		))}
		</SwipeableList>
			</div>

I expect the above code to allow a user to swipe to the left on any comment they have made and be able to delete that comment. A call to the backend would be made in the handle delete comment function, but that has not yet been implemented

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser chrome
  • Version 115.0.5790.110

Additional context
I had based my code off of the npm docs available at https://www.npmjs.com/package/react-swipeable-list and cannot see this trailingFullSwipeAction property anywhere... any help would be greatly appreciated

Max percentage swipable

Is your feature request related to a problem? Please describe.
I really like the library but I'm missing the functionality to be able to set a max percentage that the list item can be swipable

Describe the solution you'd like
Set a prop to the item for example 50% and then the item will be swipable only for 50% of it's width, and not the 100%

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Add classname prop for elements

Hey 👋🏾

first of all, I want to thank you for this awesome package that you have created here! I've been searching for a while to find a package that could replace my custom implementation and I think that your package here is really well done!

Is your feature request related to a problem? Please describe.
The only thing that I find a bit hard to follow is how to customize the com. It looks like, I can not add custom class names to these components.

Describe the solution you'd like
Would be nice if could add className as props for each component and append them to the class names that you are already using. If I understood the code base correctly, you use clsx already, so adding that option should be a big issue, is it?

Describe alternatives you've considered
Alternatively, I could make use of the style option and for the items, I have to add extra elements as children. However, when trying to use this component within an existing design system and component library, it's not really supporting the DX when you have to hard-code values like colours or spacings

Additional context

What I am trying to achieve is that I use the elements in this package and re-export them in our component library with the existing styles applied already.

So the developer would use something like

<SwipeableList.Root> which them should be <SwipeableList fullSwipe={false} type={ListType.IOS} className="styles-from-my-design-system">

incomplete closure of swipes

If you close actions with a jerk of the mouse, sometimes it does not close completely, see the screenshot
type IOS, fullSwipe enabled

Снимок экрана 2023-08-29 в 12 48 32

macOS Big Sur 11.7
Google Chrome 116.0.5845.96

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.