import React, { memo, forwardRef, useRef } from 'react';
import { usePropsResolution } from '../../../hooks/useThemeProps';
import type { ITextProps } from './types';
import { useHover } from '@react-native-aria/interactions';
import { mergeRefs } from '../../../utils/mergeRefs';
import { makeStyledComponent } from '../../../utils/styled';
import { useResolvedFontFamily } from '../../../hooks/useResolvedFontFamily';
import { Platform, Text as NativeText } from 'react-native';
import { useHasResponsiveProps } from '../../../hooks/useHasResponsiveProps';
const StyledText = makeStyledComponent(NativeText);
// To have a RN compatible behaviour, we'll inherit parent text styles as base style
const TextAncestorContext = React.createContext(false);
const Text = ({ children, ...props }: ITextProps, ref: any) => {
const hasTextAncestor = React.useContext(TextAncestorContext);
const {
isTruncated,
noOfLines,
bold,
italic,
sub,
highlight,
underline,
strikeThrough,
fontFamily: propFontFamily,
fontWeight: propFontWeight,
fontStyle: propFontStyle,
_hover,
fontSize,
numberOfLines,
...resolvedProps
} = usePropsResolution(
'Text',
props,
{},
{
resolveResponsively: ['noOfLines', 'numberOfLines'],
// We override the component base theme if text has an ancestor.
componentTheme: hasTextAncestor ? {} : undefined,
}
);
const _ref = useRef(null);
// TODO: might have to add this condition
const { isHovered } = useHover({}, _hover ? _ref : null);
// const { isHovered } = useHover({}, _ref);
let fontFamily = propFontFamily;
const fontStyle = italic ? 'italic' : propFontStyle;
const fontWeight = bold ? 'bold' : propFontWeight;
let resolvedFontFamily;
resolvedFontFamily = useResolvedFontFamily({
fontFamily,
fontWeight: fontWeight ?? (hasTextAncestor ? undefined : 400),
fontStyle: fontStyle ?? (hasTextAncestor ? undefined : 'normal'),
});
if (resolvedFontFamily) {
fontFamily = resolvedFontFamily;
}
// Need to apply fontWeight & fontStyle on web
if (Platform.OS === 'web') {
if (resolvedFontFamily) {
fontFamily = resolvedFontFamily.fontFamily;
}
resolvedFontFamily = {
fontFamily,
fontWeight: fontWeight ?? (hasTextAncestor ? undefined : 400),
fontStyle: fontStyle ?? (hasTextAncestor ? undefined : 'normal'),
};
}
//TODO: refactor for responsive prop
if (useHasResponsiveProps(props)) {
return null;
}
const propsToSpread = {
...resolvedProps,
numberOfLines:
numberOfLines || noOfLines
? numberOfLines || noOfLines
: isTruncated
? 1
: undefined,
...resolvedFontFamily,
bg: highlight ? 'warning.300' : resolvedProps.bg,
textDecorationLine:
underline && strikeThrough
? 'underline line-through'
: underline
? 'underline'
: strikeThrough
? 'line-through'
: resolvedProps.textDecorationLine,
fontSize: sub ? 10 : fontSize,
ref: mergeRefs([ref, _ref]),
...(isHovered && _hover),
};
return hasTextAncestor ? (
{children}
) : (
{children}
);
};
export default memo(forwardRef(Text));
export type { ITextProps };