import React, { useRef } from 'react'; import styled from '@emotion/native'; import { ColorName, ViewStyle } from '@emotion/react'; import { useHover } from 'react-native-web-hooks'; import { Text } from 'components/text'; import { StyleSystemThemedProps, Row, TouchableHighlight, Container, ActivityIndicator, } from 'components/layout'; import { TouchableHighlightProps as TouchableHighlightPropsBase } from 'react-native'; import { variant } from 'styled-system'; import { COLOR_VALUES } from 'theme/color'; import { TFunctionResult } from 'i18next'; import { TextVariant, TextWeightVariant } from 'components/text/Text'; import { Visible } from 'components/visible'; const variants: Record = { outline: { borderWidth: 1, }, underline: { borderBottomWidth: 2, }, 'underline-inactive': { borderColor: 'transparent', borderBottomWidth: 2, }, }; const colorVariants: Record = { primary: { backgroundColor: 'primary', }, 'primary-hover': { backgroundColor: 'primary-hover', }, secondary: { backgroundColor: 'secondary', }, 'secondary-hover': { backgroundColor: 'secondary-hover', }, body: { backgroundColor: 'body', }, caption: { backgroundColor: 'caption', }, divider: { backgroundColor: 'divider', }, title: { backgroundColor: 'title', }, base: { backgroundColor: 'base', }, transparent: { borderRadius: 'button', backgroundColor: 'transparent', }, 'base-01': { backgroundColor: 'base-01', }, 'base-02': { backgroundColor: 'base-02', }, 'base-02-hover': { backgroundColor: 'base-02-hover', }, 'base-03': { backgroundColor: 'base-03', }, }; const borderColorVariants: Record = { primary: { borderColor: 'primary', }, 'primary-hover': { borderColor: 'primary-hover', }, secondary: { borderColor: 'secondary', }, 'secondary-hover': { borderColor: 'secondary-hover', }, body: { borderColor: 'body', }, caption: { borderColor: 'caption', }, divider: { borderColor: 'divider', }, title: { borderColor: 'title', }, base: { borderColor: 'base', }, transparent: { borderColor: 'transparent', }, 'base-01': { borderColor: 'base-01', }, 'base-02': { borderColor: 'base-02', }, 'base-02-hover': { borderColor: 'base-02-hover', }, 'base-03': { borderColor: 'base-03', }, }; const sizeVariants: Record = { undefined: { height: undefined, px: undefined, }, content: { height: undefined, px: '3xs', }, 'extra-small': { height: 25, px: 'xs', }, small: { height: 30, px: 'xs', }, medium: { px: 's', height: 35, }, large: { px: 'm', height: 40, }, 'extra-large': { px: 'm', height: 45, }, '2-extra-large': { px: 'm', height: 50, }, }; const shapeVariants: Record = { square: { borderRadius: 0, }, round: { borderRadius: 'button', }, }; const ButtonLocal = styled(TouchableHighlight)( variant({ prop: 'colorVariant', variants: colorVariants, }), variant({ variants, }), variant({ prop: 'sizeVariant', variants: sizeVariants, }), variant({ prop: 'shapeVariant', variants: shapeVariants, }), variant({ prop: 'borderColorVariant', variants: borderColorVariants, }), { alignItems: 'center', justifyContent: 'center', } ); const UnderlayColors: Record = { outline: COLOR_VALUES['underlay-primary'], underline: 'transparent', 'underline-inactive': 'transparent', }; export const Button: React.FC = ({ title, loading, leftElement, titleColor, titleWeight = 'normal', colorVariant, borderColorVariant, titleVariant, centerElement, rightElement, collapsedWidth, collapsedElement, shapeVariant = 'round', underlayColorVariant, hoverColorVariant = colorVariant, hoverTitleColorVariant = titleColor, hoverBorderColor = borderColorVariant, isCollapsed, ...props }) => { const buttonRef = useRef(null); const isHovered = useHover(buttonRef); const width = isCollapsed ? collapsedWidth : undefined; const localColorVariant = isHovered ? hoverColorVariant : colorVariant; const localBorderColorVariant = isHovered ? hoverBorderColor : borderColorVariant; const notHoveredColor = localColorVariant === 'primary' ? 'white' : titleColor; const localTitleColor = isHovered ? hoverTitleColorVariant : notHoveredColor; const func = loading ? undefined : props.onPress; return ( <> {collapsedElement} <> {leftElement} {centerElement || ( {title as string} )} {rightElement} ); }; export type ButtonVariant = 'outline' | 'underline' | 'underline-inactive'; export type ButtonColorVariant = | 'primary' | 'primary-hover' | 'secondary' | 'secondary-hover' | 'base' | 'title' | 'base-01' | 'base-02' | 'base-02-hover' | 'base-03' | 'body' | 'divider' | 'caption' | 'transparent'; export type ButtonSizeVariant = | 'undefined' | 'content' | 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large' | '2-extra-large'; type ButtonShapeVariant = 'square' | 'round'; export type ButtonType = StyleSystemThemedProps & TouchableHighlightProps & ButtonProps; export interface TouchableHighlightProps extends TouchableHighlightPropsBase { variant?: ButtonVariant; sizeVariant?: ButtonSizeVariant; colorVariant?: ButtonColorVariant; borderColorVariant?: ButtonColorVariant; shapeVariant?: ButtonShapeVariant; } export interface ButtonProps { title?: string | number | TFunctionResult; centerElement?: JSX.Element; titleColor?: ColorName; titleWeight?: TextWeightVariant; titleVariant?: TextVariant; leftElement?: JSX.Element; rightElement?: JSX.Element; collapsedElement?: JSX.Element; collapsedWidth?: number; isCollapsed?: boolean; loading?: boolean; underlayColorVariant?: ColorName; hoverColorVariant?: ButtonColorVariant; hoverBorderColor?: ButtonColorVariant; hoverTitleColorVariant?: ColorName; }