marekrozmus / react-swipeable-list Goto Github PK
View Code? Open in Web Editor NEWSwipeable list component for React supporting several behaviours (e.g. iOS)
Home Page: https://marekrozmus.github.io/react-swipeable-list/
License: MIT License
Swipeable list component for React supporting several behaviours (e.g. iOS)
Home Page: https://marekrozmus.github.io/react-swipeable-list/
License: MIT License
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:
onSwipeStart
will triggeronSwipeStart
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.
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!
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.
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.
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
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):
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">
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.
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
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
But the same code work fine in codesandbox as you can see in below attach gif
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
Currently it's impossible to use react-swipeable-list with fragments because it breaks and actions does not work.
Swipe action triggers onClick event
Steps to reproduce the behavior:
Expected behavior:
onClick should work apart from swipe actions
Desktop (please complete the following information):
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>
Describe the bug
Swipe actions dont appear behind my item
To Reproduce I have deployed the proyect for trying in production, but also not working
https://budget-management-three.vercel.app/
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):
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
Is it possible to implement it?
This would look good in onSwiperProgress
Eg:
(progress: number, direction: string) => void
Describe the bug
maxSwipe prop is not optional
https://github.com/marekrozmus/react-swipeable-list/blob/main/src/module.d.ts#L180
To Reproduce
SwipeableListItem
component without passing maxSwipe
propExpected behavior
Prop should be optional as per the docs
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
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.
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..
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?
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
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):
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,
});
});
}
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:
Alternatively, would it be possible for you to provide a reset API that would allow us to manually close the `<SwipeableListItem>` components?
This could be very useful for users who want to leave multiple items open at once, or for those who prefer to have only one item open at a time.
Originally posted by @edwardfxiao in #37 (comment)
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?
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
When an item is deleted from the list, the item below it comes in its place with animation.
Right now the speed of that animation(moving up) is fast. I want to slow down the speed of that animation.
Can you please provide option to set its speed.
Another option to setting its animation type would be great as well
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.