import MaskedView from '@react-native-masked-view/masked-view';
import { LinearGradient } from 'expo-linear-gradient';
import React, { useCallback, useState } from 'react';
import type { AccessibilityProps, LayoutChangeEvent } from 'react-native';
import { View } from 'react-native';
import { useTheme } from '../../../theme';
interface GradientTextProps extends AccessibilityProps {
children: React.ReactNode;
}
const GradientText = ({
children,
...accessibilityProps
}: GradientTextProps) => {
const theme = useTheme();
const gradient = theme.colors.gradients.aiDiagonal;
const [size, setSize] = useState<{ width: number; height: number } | null>(
null
);
const onLayout = useCallback((event: LayoutChangeEvent) => {
const { width, height } = event.nativeEvent.layout;
setSize((prevSize) => {
if (prevSize && prevSize.width === width && prevSize.height === height) {
return prevSize;
}
return { width, height };
});
}, []);
return (
{/*
* MaskedView is entirely hidden from the accessibility tree.
* It is purely visual: the mask defines the text clip shape and
* the content shows either a gradient or a visible fallback.
* Screen readers must not traverse into either branch here.
*/}
{children}
}
>
{size ? (
) : (
// Render children as fallback until layout is measured, so text
// is visible immediately rather than blank on the first frame.
children
)}
{/*
* Visually hidden but accessible: the single Text node that
* screen readers announce. Kept outside MaskedView so it is
* always present and never duplicated.
*/}
{children}
);
};
export default GradientText;