marekrozmus / react-swipeable-list

Swipeable list component for React supporting several behaviours (e.g. iOS)
https://marekrozmus.github.io/react-swipeable-list/
MIT License
114 stars 20 forks source link

_this.trailingFullSwipeAction is not a function #22

Closed Judahh closed 2 years ago

Judahh commented 2 years ago

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:

marekrozmus commented 2 years ago

Hi, In const actions = ({id, name}) => { - are you always return the

const actions = (<LeadingActions>
      {actionElements}
    </LeadingActions>);

even for trailingActions={actions({id: element?.id, name: 'Trailing'})}?

I mean returning <LeadingActions> for trailing actions?

Judahh commented 2 years ago

You're right! my bad. I spend a hole night in this and I didn't see this. Thanks a LOT!