import MaskedView from '@react-native-masked-view/masked-view'; import { Image, ImageProps, ImageStyle, ImageTransition, ImageContentFit } from 'expo-image'; import { SquircleView } from 'expo-squircle-view'; import React from 'react'; import { DimensionValue, StyleSheet } from 'react-native'; const styles = StyleSheet.create({ maskBase: { flex: 1, backgroundColor: 'black', }, imageFill: { width: '100%', height: '100%', }, }); export type SquircleImageProps = Omit & { /** * Style for the image. Must include width, height, and borderRadius. */ style?: ImageStyle & { width?: DimensionValue; height?: DimensionValue; borderRadius?: number; }; /** * Controls the amount of smoothing for the radius. * 0 means no smoothing, 100 means maximum smoothing. * @default 100 */ cornerSmoothing?: number; /** * Enhanced rounding for larger borderRadius values when true. * @default true */ preserveSmoothing?: boolean; /** * Blurhash string for placeholder image while loading. * @see https://blurha.sh/ */ placeholderHash?: string; /** * Content fit mode for the placeholder. * @default 'cover' */ placeholderContentFit?: ImageContentFit; /** * Image transition configuration. * Can be a number (duration in ms) or an ImageTransition object. * @default { duration: 300, effect: 'cross-dissolve', timing: 'ease-in-out' } */ transition?: ImageTransition | number | null; /** * Determines whether and where to cache the image. * - 'none' - Image is not cached at all. * - 'disk' - Image is cached on disk. * - 'memory' - Image is cached in memory only. * - 'memory-disk' - Image is cached in memory with disk fallback. * @default 'memory-disk' */ cachePolicy?: 'none' | 'disk' | 'memory' | 'memory-disk'; }; const DEFAULT_TRANSITION: ImageTransition = { duration: 300, effect: 'cross-dissolve', timing: 'ease-in-out', }; /** * An image component with squircle (iOS-style smooth corner) clipping. * Uses MaskedView with SquircleView to properly clip images with smooth corners. * Supports blurhash placeholders, smooth transitions, and configurable caching. * * @example * ```tsx * * ``` */ export function SquircleImage({ style, cornerSmoothing = 100, preserveSmoothing = true, placeholderHash, placeholderContentFit = 'cover', transition = DEFAULT_TRANSITION, cachePolicy = 'memory-disk', ...imageProps }: SquircleImageProps) { const flatStyle = StyleSheet.flatten(style); const { width, height, borderRadius = 0 } = flatStyle || {}; if (typeof __DEV__ !== 'undefined' && __DEV__ && (!width || !height)) { console.warn( 'SquircleImage: width and height must be specified in style for proper rendering' ); } return ( } > ); } export default SquircleImage;