React Native Async Button

import React, { useState } from "react";
import {
  TouchableOpacity,
  View,
  Text,
  ActivityIndicator,
  Platform,
} from "react-native";
import { FontAwesome5 } from "@expo/vector-icons";
import tailwind from "twrnc";

const tw = (styles, customStyles = {}, name) => {
  const custom = name ? customStyles[name] : "";
  return tailwind`${styles} ${custom}`;
};

export const Button = (props) => {
  const { text, loadingText, icon, isLoading, onPress, onLongPress } = props;
  const styles = props?.styles || {};
  return (
    <TouchableOpacity
      style={[
        tw("rounded-lg", styles, "container"),
        {
          ...(Platform.OS === "web"
            ? {
                // outlineColor: getColor("primary-400"),
                outlineColor: "transparent",
                outlineWidth: 2,
              }
            : {}),
        },
      ]}
      onPress={onPress}
      onLongPress={onLongPress}
    >
      <View
        style={[
          tw(
            "w-full h-10 flex items-center justify-center bg-blue-500 rounded-lg",
            styles,
            "button"
          ),
        ]}
      >
        {isLoading ? (
          <View style={tw("w-full flex flex-row justify-center items-center")}>
            <ActivityIndicator
              color={tw("text-white", styles, "loading").color}
            />
            {loadingText && (
              <Text
                style={tw(
                  "text-center text-white text-base pl-2",
                  styles,
                  "loadingText"
                )}
              >
                {loadingText}
              </Text>
            )}
          </View>
        ) : (
          <View style={tw("flex flex-row items-center", styles, "content")}>
            {text && (
              <Text
                style={tw(
                  "text-center text-white text-base leading-none",
                  styles,
                  "text"
                )}
              >
                {text}
              </Text>
            )}
            {icon && (
              <FontAwesome5
                solid={true}
                name={icon}
                style={tw("text-white p-2", styles, "icon")}
              />
            )}
          </View>
        )}
      </View>
    </TouchableOpacity>
  );
};

export const timeout = async (ms: number) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(true);
    }, ms);
  });
};

export default function App() {
  const [isLoading, SetIsLoading] = useState(false);
  return (
    <View
      style={tw(
        "flex-1 w-full px-4 py-12 flex justify-between items-center mx-auto max-w-[400px]"
      )}
    >
      <View style={tw("w-full")}>
        <Text style={tw("font-medium text-gray-400 pb-2 px-2")}>Text</Text>
        <Button
          text="Submit"
          isLoading={isLoading}
          onPress={async () => {
            SetIsLoading(true);
            await timeout(3000);
            SetIsLoading(false);
          }}
        />
      </View>
      <View style={tw("w-full")}>
        <Text style={tw("font-medium text-gray-400 pb-2 px-2")}>Icon</Text>
        <Button
          icon="arrow-right"
          isLoading={isLoading}
          onPress={async () => {
            SetIsLoading(true);
            await timeout(3000);
            SetIsLoading(false);
          }}
        />
      </View>
      <View style={tw("w-full")}>
        <Text style={tw("font-medium text-gray-400 pb-2 px-2")}>
          Text & Icon
        </Text>
        <Button
          text="Submit"
          icon="arrow-right"
          isLoading={isLoading}
          onPress={async () => {
            SetIsLoading(true);
            await timeout(3000);
            SetIsLoading(false);
          }}
        />
      </View>
      <View style={tw("w-full")}>
        <Text style={tw("font-medium text-gray-400 pb-2 px-2")}>
          Custom Loading Text
        </Text>
        <Button
          text="Submit"
          loadingText="Submitting..."
          isLoading={isLoading}
          onPress={async () => {
            SetIsLoading(true);
            await timeout(3000);
            SetIsLoading(false);
          }}
        />
      </View>
      <View style={tw("w-full")}>
        <Text style={tw("font-medium text-gray-400 pb-2 px-2")}>
          Custom Styling
        </Text>
        <Button
          styles={{
            button: "bg-pink-500",
            text: "text-orange-200",
            loading: "text-teal-200",
          }}
          text="Submit"
          isLoading={isLoading}
          onPress={async () => {
            SetIsLoading(true);
            await timeout(3000);
            SetIsLoading(false);
          }}
        />
      </View>
    </View>
  );
}