Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

renderSuggestions scrolling not working in android #113

Open
kashee-lv opened this issue Mar 12, 2023 · 17 comments
Open

renderSuggestions scrolling not working in android #113

kashee-lv opened this issue Mar 12, 2023 · 17 comments
Labels
help wanted Extra attention is needed v3 Feature and fixes for the major v3 release

Comments

@kashee-lv
Copy link

kashee-lv commented Mar 12, 2023

Hi I want to scroll the suggestion list but i am facing issue with android and its working in ios, below is my code for renderSuggestions function

`
const renderSuggestions = ({keyword, onSuggestionPress}) => {
if (
keyword === null ||
keyword === undefined ||
mappedMembers.length === 0
) {
return null;
}
const suggestionArrayToRender = mappedMembers.filter(item =>
item.name.toLowerCase().includes(keyword.toLowerCase()),
);

return (
  <View
    style={{
      // backgroundColor: 'red',
      width: 200,
      borderColor: 'gray',
      borderWidth: 0.5,
      opacity: 1,
    }}>
    <ScrollView nestedScrollEnabled style={{flexGrow: 1, height: 200}}>
      {suggestionArrayToRender
        .filter(item =>
          item.name.toLowerCase().includes(keyword.toLowerCase()),
        )
        .map(one => (
          <Pressable
            key={one.id}
            onPress={() => onSuggestionPress(one)}
            style={{padding: 12}}>
            <Text style={{color: COLORS.textBlack}}>{one.name}</Text>
          </Pressable>
        ))}
    </ScrollView>
  </View>
);

}
`

@MariusCatanoiu
Copy link

I have the same issue

@fukemy
Copy link

fukemy commented Apr 24, 2023

any solution?

@kashee-lv
Copy link
Author

@fukemy not yet please let me know if you find any thing.

@fukemy
Copy link

fukemy commented Apr 24, 2023

could you try to use ScrollView from 'react-native-gesture-handler'?

@kashee-lv
Copy link
Author

@fukemy no i am using ScrollView from react-native.

@MariusCatanoiu
Copy link

@fukemy I tried it a month ago. Same thing

@fukemy
Copy link

fukemy commented Apr 24, 2023

ok i will give my solution

@kashee-lv
Copy link
Author

kashee-lv commented Apr 25, 2023

@fukemy how you plugin your MentionView function with <MentionInput/>

@fukemy
Copy link

fukemy commented Apr 25, 2023

@fukemy how you plugin your MentionView function with <MentionInput/>

I am using ref to share the trigger data between MentionView and InputView

@kashee-lv
Copy link
Author

@fukemy how you plugin your MentionView function with <MentionInput/>

I am using ref to share the trigger data between MentionView and InputView

I hope you don't mind to share the code snippet, please

@kashee-lv
Copy link
Author

@fukemy I tried to implement as you shared the code but i am facing some issues,

  1. its not filtering the list data as i am typing in TextInput
  2. List is rendering between the UI, I am expecting it should be appear as model

Simulator Screen Shot - iPhone 14 - 2023-04-29 at 18 50 58

Simulator Screen Shot - iPhone 14 - 2023-04-29 at 19 00 18

@Choyeongdeok
Copy link

I solved it by using FlatList from react-native-gesture-handler.
when I used FlatList from react-native with position: 'absolute', the scroll doesn't work.

@MariusCatanoiu
Copy link

I solved it by using FlatList from react-native-gesture-handler. when I used FlatList from react-native with position: 'absolute', the scroll doesn't work.

I tried it some time ago, is not working for me.

@yessinej
Copy link

yessinej commented Aug 2, 2023

any update about this topic ?

@Choyeongdeok
Copy link

Choyeongdeok commented Aug 3, 2023

my code using FlatList from react-native-gesture-handler

    const renderSuggestions = ({ keyword = null, onSuggestionPress }) => {
        if(keyword === null) return null

        return (
            <View
                style={{
                    position: 'absolute',
                    bottom: inputHeight + 10,
                    width: deviceWidth,
                    left: -13,
                }}
            >
                <Shadow // react-native-shadow-2
                    startColor='rgba(0, 0, 0, 0.05)'
                    corners={{
                        topStart: true,
                        topEnd: true
                    }}
                    distance={12}
                    sides={{
                        top: true,
                        bottom: false
                    }}
                >
                <FlatList // react-native-gesture-handler
                    data={suggestions.filter(member => member?.name?.toLocaleLowerCase()?.includes(keyword?.toLocaleLowerCase()))}
                    renderItem={({ item }) => renderItem({ item, keyword, onSuggestionPress })}
                    keyboardShouldPersistTaps='always'
                    ListFooterComponent={() => (
                        <View style={{ height: 12 }}/>
                    )}
                    style={{
                        maxHeight: 230,
                        backgroundColor: '#FFFFFF',
                        borderTopRightRadius: 16,
                        borderTopLeftRadius: 16,
                        borderWidth: 1,
                        borderColor: '#E9E9E9',
                    }}
                />
            </Shadow>
            </View>
        )
    }
KakaoTalk_Video_2023-08-03-09-06-52.mp4

@kashee-lv
Copy link
Author

It works well when you use it out side of the Flatlist, but problem happens when you use it over the scrollView

@dabakovich
Copy link
Owner

Hey all!

Thanks for using the library and providing your feedbacks.

I've also encountered this problem in my projects. The most compromising solution was using the Portal pattern. You can use this component from the react-native-paper library, from a separate library @gorhom/portal, or you can implement this component yourself.

Here is a very basic and simplified example that I used in production:

import * as React from 'react';
import { FC, useRef, useState } from 'react';
import { FlatList, Pressable, Text, TextInput, View } from 'react-native';
import {
  Suggestion,
  SuggestionsProvidedProps,
  TriggersConfig,
  useMentions,
} from 'react-native-controlled-mentions/dist';
import { Portal, PortalProvider } from '@gorhom/portal';
import { hashtags, messages } from './constants';

// Custom component for rendering suggestions
const Suggestions: FC<
  SuggestionsProvidedProps & { suggestions: Suggestion[]; inputHeight: number }
> = ({ keyword, onSelect, suggestions, inputHeight }) => {
  if (keyword == null) {
    return null;
  }

  return (
    <Portal>
      <View
        style={{
          position: 'absolute',
          width: '100%',
          maxHeight: 200,
          padding: 12,
          bottom: inputHeight,
        }}>
        <FlatList
          style={{
            backgroundColor: 'white',
            borderRadius: 12,
            borderWidth: 1,
            borderColor: 'grey',
          }}
          data={suggestions.filter(one =>
            one.name.toLocaleLowerCase().includes(keyword.toLocaleLowerCase()),
          )}
          renderItem={({ item }) => (
            <Pressable
              key={item.id}
              onPress={() => onSelect(item)}
              style={{ padding: 12 }}>
              <Text>{item.name}</Text>
            </Pressable>
          )}
          keyExtractor={item => item.id.toString()}
          keyboardShouldPersistTaps="handled"
        />
      </View>
    </Portal>
  );
};

// Config of suggestible triggers
const triggersConfig: TriggersConfig<'hashtag'> = {
  hashtag: {
    trigger: '#',
    textStyle: {
      fontWeight: 'bold',
      color: 'grey',
    },
  },
};

const MentionsFunctionalComponent = () => {
  const textInput = useRef<TextInput>(null);

  const [inputHeight, setInputHeight] = useState(0);

  const [textValue, setTextValue] = useState('Hello Mary! How are you?');

  const { textInputProps, triggers, mentionState } = useMentions({
    value: textValue,
    onChange: setTextValue,

    triggersConfig,
  });

  return (
    <PortalProvider>
      <View style={{ flex: 1, justifyContent: 'flex-end' }}>
        <FlatList
          data={messages}
          renderItem={({ item }) => (
            <Text style={{ padding: 10 }}>{item.text}</Text>
          )}
          keyExtractor={item => item.id.toString()}
        />

        <Suggestions
          suggestions={hashtags}
          {...triggers.hashtag}
          inputHeight={inputHeight}
        />

        <TextInput
          ref={textInput}
          multiline
          onLayout={event => {
            setInputHeight(event.nativeEvent.layout.height);
          }}
          placeholder="Type here..."
          style={{ padding: 12 }}
          {...textInputProps}
        />
      </View>
    </PortalProvider>
  );
};

export { MentionsFunctionalComponent };

Please note that for iOS there's no need to use Portal as scrolling together with position: 'absolute' works fine. Thus, you can use the following selector for root component in Suggestions:

const Component = Platform.OS === 'ios' ? Fragment : Portal;

@dabakovich dabakovich added help wanted Extra attention is needed v3 Feature and fixes for the major v3 release labels Sep 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed v3 Feature and fixes for the major v3 release
Projects
None yet
Development

No branches or pull requests

6 participants