import React, { memo, forwardRef } from 'react';
import Spinner from '../Spinner';
import { usePropsResolution } from '../../../hooks/useThemeProps';
import { default as Box, IBoxProps } from '../Box';
import HStack from '../Stack/HStack';
import { Pressable } from '../Pressable';
import type { IButtonProps } from './types';
import { composeEventHandlers } from '../../../utils';
import {
useHover,
useFocus,
useIsPressed,
} from '../../primitives/Pressable/Pressable';
import { useFocusRing } from '@react-native-aria/focus';
import { useHasResponsiveProps } from '../../../hooks/useHasResponsiveProps';
const Button = (
{
//@ts-ignore
children,
startIcon,
rightIcon,
leftIcon,
endIcon,
spinner,
isDisabled,
isLoading,
isHovered: isHoveredProp,
isPressed: isPressedProp,
isFocused: isFocusedProp,
isFocusVisible: isFocusVisibleProp,
spinnerPlacement = 'start',
...props
}: IButtonProps & IBoxProps,
ref: any
) => {
const { hoverProps, isHovered } = useHover();
const { pressableProps, isPressed } = useIsPressed();
const { focusProps, isFocused } = useFocus();
const { isFocusVisible, focusProps: focusRingProps }: any = useFocusRing();
const {
onPressIn,
onPressOut,
onHoverIn,
onHoverOut,
onFocus,
onBlur,
_text,
_stack,
_spinner,
isLoadingText,
_icon,
...resolvedProps
} = usePropsResolution('Button', props, {
isDisabled,
isHovered: isHoveredProp || isHovered,
isFocused: isFocusedProp || isFocused,
isPressed: isPressedProp || isPressed,
isLoading,
isFocusVisible: isFocusVisibleProp || isFocusVisible,
});
//TODO: refactor for responsive prop
if (useHasResponsiveProps(props)) {
return null;
}
if (leftIcon) {
startIcon = leftIcon;
}
if (rightIcon) {
endIcon = rightIcon;
}
if (endIcon && React.isValidElement(endIcon)) {
endIcon = React.Children.map(
endIcon,
(child: JSX.Element, index: number) => {
return React.cloneElement(child, {
key: `button-end-icon-${index}`,
..._icon,
...child.props,
});
}
);
}
if (startIcon && React.isValidElement(startIcon)) {
startIcon = React.Children.map(
startIcon,
(child: JSX.Element, index: number) => {
return React.cloneElement(child, {
key: `button-start-icon-${index}`,
..._icon,
...child.props,
});
}
);
}
const spinnerElement = spinner ? (
spinner
) : (
);
const boxChildren = (child: any) => {
return child ? {child} : null;
};
return (
{startIcon && !isLoading ? startIcon : null}
{isLoading && spinnerPlacement === 'start' ? spinnerElement : null}
{isLoading
? isLoadingText
? boxChildren(isLoadingText)
: null
: boxChildren(children)}
{endIcon && !isLoading ? endIcon : null}
{isLoading && spinnerPlacement === 'end' ? spinnerElement : null}
);
};
export default memo(forwardRef(Button));