react-native-controlled-mentions icon indicating copy to clipboard operation
react-native-controlled-mentions copied to clipboard

renderSuggestions scrolling not working in android

Open kashee-lv opened this issue 1 year ago • 17 comments

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>
);

} `

kashee-lv avatar Mar 12 '23 13:03 kashee-lv

I have the same issue

MariusCatanoiu avatar Mar 21 '23 14:03 MariusCatanoiu

any solution?

fukemy avatar Apr 24 '23 08:04 fukemy

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

kashee-lv avatar Apr 24 '23 13:04 kashee-lv

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

fukemy avatar Apr 24 '23 13:04 fukemy

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

kashee-lv avatar Apr 24 '23 13:04 kashee-lv

@fukemy I tried it a month ago. Same thing

MariusCatanoiu avatar Apr 24 '23 18:04 MariusCatanoiu

ok i will give my solution

fukemy avatar Apr 24 '23 19:04 fukemy

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

kashee-lv avatar Apr 25 '23 05:04 kashee-lv

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

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

fukemy avatar Apr 25 '23 15:04 fukemy

@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 avatar Apr 25 '23 16:04 kashee-lv

@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

kashee-lv avatar Apr 29 '23 13:04 kashee-lv

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.

Choyeongdeok avatar Jul 25 '23 02:07 Choyeongdeok

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.

MariusCatanoiu avatar Jul 25 '23 06:07 MariusCatanoiu

any update about this topic ?

yessinej avatar Aug 02 '23 15:08 yessinej

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>
        )
    }

https://github.com/dabakovich/react-native-controlled-mentions/assets/54658590/64680737-905e-4d78-b782-4f11dab5cfa6

Choyeongdeok avatar Aug 03 '23 00:08 Choyeongdeok

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

kashee-lv avatar Aug 03 '23 06:08 kashee-lv

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 avatar Sep 16 '23 11:09 dabakovich