| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import { Colors } from '@/constants/theme';
- import { isPromise } from '@/utils/tsutils';
- import { ActivityIndicator, Icon } from '@ant-design/react-native';
- import { type IconNames } from '@ant-design/react-native/lib/icon';
- import { clsx } from 'clsx';
- import { Href, Link } from "expo-router";
- import React, { useCallback, useEffect, useMemo, useState } from "react";
- import { Pressable, Text, View, ViewStyle } from "react-native";
- interface UIButtonProps {
- children?: string | React.ReactNode;
- title?: string | React.ReactNode;
- onPress?: () => PromiseLike<unknown> | unknown;
- disabled?: boolean;
- className?: string;
- textClassName?: string;
- href?: Href
- type?: 'primary' | 'second' | 'link'
- icon?: IconNames | React.ReactNode;
- style?: ViewStyle;
- loading?: boolean;
- }
- function ButtonTextChild({ type, disabled, textClassName, children, loading }: UIButtonProps) {
- return loading ? <View className='flex-row justify-center items-center'>
- <ActivityIndicator color={disabled ? '#888' : Colors['on-primary']['DEFAULT']} />
- <Text className={clsx(
- textClassName,
- 'ml-1',
- 'text-xl font-bold', {
- 'text-on-primary': !disabled && type === 'primary',
- 'text-primary': !disabled && type !== 'primary',
- 'text-secondary': !disabled && type === 'second',
- 'text-on-surface': !disabled && !type,
- 'text-on-surface-variant/65 font-normal': disabled,
- })}>{children}</Text>
- </View> : <Text className={clsx(
- textClassName,
- 'text-xl font-bold', {
- 'text-on-primary': !disabled && type === 'primary',
- 'text-primary': !disabled && type !== 'primary',
- 'text-secondary': !disabled && type === 'second',
- 'text-on-surface': !disabled && !type,
- 'text-on-surface-variant/65 font-normal': disabled,
- })}>{children}</Text>
- }
- export default function UIButton({ onPress, href, type, icon, className, style, disabled, children, title, textClassName, loading }: UIButtonProps) {
- const [ding, setDing] = useState(loading);
- useEffect(() => {
- setDing(loading);
- }, [loading])
- children = children || title;
- const handlePress = useCallback(() => {
- const res = onPress?.() as Promise<any> || undefined;
- if (isPromise(res)) {
- setDing(true);
- res.finally(() => {
- setDing(false);
- })
- }
- }, []);
- const inner = useMemo(() => <Pressable
- className={clsx('h-14 rounded-3xl flex-row justify-center items-center border-2 opacity-100 active:opacity-75 active:scale-95',
- className, {
- 'bg-primary border-primary': type === 'primary',
- 'bg-surface border-primary/25': !type,
- 'bg-surface border-on-surface/25': type === 'second',
- 'bg-transparent border-transparent': type === 'link',
- 'bg-primary-fixed-dim border-primary-fixed-dim': disabled && type === 'primary',
- 'bg-gray-300 border-gray-300': disabled && !type,
- 'bg-bg-gray-400 border-gray-200': disabled && type === 'second'
- })}
- disabled={disabled}
- onPress={handlePress}
- style={style}>
- {typeof icon === 'string' ? <Icon name={icon as IconNames} size={24} style={{ marginRight: 4, color: disabled ? Colors['on-surface']['variant'] : type === 'primary' ? '#fff' : type === 'second' ? Colors.secondary.DEFAULT : Colors.primary.DEFAULT }} /> : icon}
- {typeof children == 'string' ? <ButtonTextChild type={type} disabled={disabled} loading={loading} textClassName={textClassName}>{children}</ButtonTextChild> : children}
- </Pressable >, [children, className, disabled, icon, onPress, style, textClassName, type])
- if (typeof href !== 'undefined') {
- return <Link href={href} asChild>
- {inner}
- </Link>
- }
- return inner;
- }
|