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

The input field becomes laggy after updating to Expo SDK 52 #95

Open
hrr2000 opened this issue Nov 22, 2024 · 5 comments
Open

The input field becomes laggy after updating to Expo SDK 52 #95

hrr2000 opened this issue Nov 22, 2024 · 5 comments
Labels
question Further information is requested

Comments

@hrr2000
Copy link

hrr2000 commented Nov 22, 2024

While typing using the Android keyboard, the input field becomes laggy and gives the effect of debouncing the input, if I tried to type twice sequentially it only takes the first number and doesn't take the second, I need to type again. Also while trying to hold on delete it stops after deleting 2 or 3 characters only and is slow too.

@AstrOOnauta AstrOOnauta added the question Further information is requested label Nov 25, 2024
@AstrOOnauta
Copy link
Owner

AstrOOnauta commented Nov 25, 2024

Hey @hrr2000 can you send more informations about this case?

I use this library in my projects and it doesn't happen. I tested demo with an Android smartphone and it didn't happen... (the demo is set up with SDK 52).

@KMJ-007
Copy link

KMJ-007 commented Nov 28, 2024

facing same issue

@KMJ-007
Copy link

KMJ-007 commented Nov 28, 2024

laggy:

  • when i type digits fast some digits are getting skipped
  • when long pressing on delete button from keyboard, it doesn't the entire number

@luisnquin
Copy link

Workaround:

keyboardType="number-pad"

@KMJ-007
Copy link

KMJ-007 commented Nov 30, 2024

i eneded up building my own component, and which is like crazy fast

import { countries } from "@/constants/countries";
import { cn } from "@/utils/utils";
import { Ionicons } from "@expo/vector-icons";
import { CountryCode } from "libphonenumber-js";
import { useCallback, useMemo, useState } from "react";
import {
  FlatList,
  Modal,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from "react-native";


interface Country {
  name: string;
  flag: string;
  code: CountryCode;
  dialCode: string;
}

export interface PhoneInputStyleConfig {
  container?: string;
  countryButton?: string;
  countryFlag?: string;
  countryDialCode?: string;
  input?: string;
  modal?: {
    container?: string;
    content?: string;
    header?: string;
    headerText?: string;
    closeButton?: string;
    searchContainer?: string;
    searchInput?: string;
    listItem?: string;
    listItemFlag?: string;
    listItemText?: string;
    listItemDialCode?: string;
  };
}

interface PhoneNumberInputProps {
  value: string;
  onChangePhoneNumber: (value: string) => void;
  selectedCountry: Country;
  onChangeSelectedCountry: (country: Country) => void;
  autoFocus?: boolean;
  placeholder?: string;
  disabled?: boolean;
  styles?: PhoneInputStyleConfig;
}

export function PhoneNumberInput({
  value,
  onChangePhoneNumber,
  selectedCountry,
  onChangeSelectedCountry,
  autoFocus = false,
  placeholder = "Enter your phone number",
  disabled = false,
  styles,
}: PhoneNumberInputProps) {
  const [modalVisible, setModalVisible] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");

  const filteredCountries = useMemo(() => {
    return countries.filter(
      (country) =>
        country.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
        country.dialCode.includes(searchQuery) ||
        country.code.toLowerCase().includes(searchQuery.toLowerCase())
    );
  }, [searchQuery]);

  const handleCountrySelect = useCallback((country: Country) => {
    onChangeSelectedCountry(country);
    setModalVisible(false);
    setSearchQuery("");
  }, [onChangeSelectedCountry]);

  const closeModal = useCallback(() => {
    setModalVisible(false);
    setSearchQuery("");
  }, []);

  const renderCountryItem = useCallback(({ item }: { item: Country }) => (
    <TouchableOpacity
      onPress={() => handleCountrySelect(item)}
      className={cn(
        "flex-row items-center mx-2 px-4 py-3.5 rounded-xl active:bg-surface/50",
        styles?.modal?.listItem
      )}
    >
      <Text className={cn("text-2xl mr-4", styles?.modal?.listItemFlag)}>
        {item.flag}
      </Text>
      <View className="flex-1">
        <Text className={cn("text-base font-medium text-text-primary", styles?.modal?.listItemText)}>
          {item.name}
        </Text>
        <Text className={cn("text-sm text-text-tertiary mt-0.5", styles?.modal?.listItemDialCode)}>
          {item.dialCode}
        </Text>
      </View>
    </TouchableOpacity>
  ), [handleCountrySelect, styles]);

  return (
    <>
      <View 
        className={cn(
          "flex-row items-center border border-border rounded-xl overflow-hidden h-14",
          styles?.container
        )}
      >
        <TouchableOpacity
          onPress={() => setModalVisible(true)}
          disabled={disabled}
          className={cn(
            "flex-row items-center px-4 space-x-2 border-r border-border h-full",
            styles?.countryButton
          )}
        >
          <Text className={cn("text-2xl", styles?.countryFlag)}>
            {selectedCountry.flag}
          </Text>
          <Text className={cn("text-base font-medium text-text-primary min-w-[45px]", styles?.countryDialCode)}>
            {selectedCountry.dialCode}
          </Text>
          <Ionicons
            name="chevron-down"
            className="text-text-primary text-base"
          />
        </TouchableOpacity>

        <TextInput
          value={value}
          onChangeText={onChangePhoneNumber}
          keyboardType="phone-pad"
          autoFocus={autoFocus}
          editable={!disabled}
          placeholder={placeholder}
          className={cn(
            "flex-1 h-full px-4 text-lg font-medium text-text-primary placeholder:text-text-tertiary",
            styles?.input
          )}
        />
      </View>

      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={closeModal}
      >
        <View className={cn("flex-1 bg-black/50", styles?.modal?.container)}>
          <View className={cn("flex-1 mt-24 bg-card rounded-t-3xl", styles?.modal?.content)}>
            <View className={cn(
              "flex-row items-center justify-between px-6 py-4",
              styles?.modal?.header
            )}>
              <Text className={cn("text-xl font-semibold text-text-primary", styles?.modal?.headerText)}>
                Select Country
              </Text>
              <TouchableOpacity
                onPress={closeModal}
                hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                className={cn(
                  "p-1.5 rounded-full bg-surface/30 active:bg-surface/50",
                  styles?.modal?.closeButton
                )}
              >
                <Ionicons
                  name="close"
                  className="text-text-tertiary text-lg"
                />
              </TouchableOpacity>
            </View>

            <View className={cn("px-4 pt-2 pb-3", styles?.modal?.searchContainer)}>
              <View className="flex-row items-center bg-surface/30 rounded-full px-4 shadow-sm">
                <Ionicons
                  name="search-outline"
                  className="text-text-tertiary text-lg mr-2"
                />
                <TextInput
                  value={searchQuery}
                  onChangeText={setSearchQuery}
                  placeholder="Search countries"
                  placeholderTextColor="#666"
                  className={cn(
                    "flex-1 h-11 text-base text-text-primary placeholder:text-text-tertiary",
                    styles?.modal?.searchInput
                  )}
                />
                {searchQuery.length > 0 && (
                  <TouchableOpacity
                    onPress={() => setSearchQuery("")}
                    hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                  >
                    <Ionicons
                      name="close-circle"
                      className="text-text-tertiary text-lg"
                    />
                  </TouchableOpacity>
                )}
              </View>
            </View>

            <FlatList
              data={filteredCountries}
              keyExtractor={(item) => item.code}
              renderItem={renderCountryItem}
              initialNumToRender={20}
              maxToRenderPerBatch={20}
              windowSize={10}
              keyboardShouldPersistTaps="handled"
              className="bg-card px-2"
              contentContainerClassName="py-2"
              ItemSeparatorComponent={() => <View className="h-[1px] bg-surface/50 mx-4" />}
            />
          </View>
        </View>
      </Modal>
    </>
  );
} 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants