UNPKG

@danielsaraldi/react-native-blur-view

Version:
515 lines (393 loc) 23.2 kB
# `@danielsaraldi/react-native-blur-view` 🌫️ A simple blur view in react native based in [`@react-native-community/blur`](https://github.com/margelo/react-native-blur). Support the animation transitions with [react-native-screens](https://github.com/software-mansion/react-native-screens), [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated/), [react-native-navigation](https://github.com/wix/react-native-navigation) and Modals 😁. This library supports Apple TV and Android TV! 📺 > [!WARNING] > Bottom tabs customized with the [react-navigation/bottom-tabs](https://reactnavigation.org/docs/bottom-tab-navigator/) aren't supported in Android. For more information, just [click here](https://github.com/DanielAraldi/react-native-blur-view/issues/39#issuecomment-4081708642)! <div align="center"> <p> <img alt="GitHub package.json version" src="https://img.shields.io/github/package-json/v/DanielAraldi/react-native-blur-view?style=flat&color=brightgreen" /> <img alt="Unpacked size" src="https://img.shields.io/npm/unpacked-size/%40danielsaraldi%2Freact-native-blur-view?style=flat&color=brightgreen" /> <img alt="NPM Downloads" src="https://img.shields.io/npm/dm/%40danielsaraldi%2Freact-native-blur-view?style=flat" /> </p> </div> > [!NOTE] > This package supports **only** [new architecture](https://reactnative.dev/blog/2024/10/23/the-new-architecture-is-here). <p align="center"> <img height="756px" hspace="8" src="./.github/previews/ios.gif" alt="React Native Blur View on iOS" /> <img height="756px" hspace="8" src="./.github/previews/android.gif" alt="React Native Blur View on Android" /> </p> ## Summary - [Installation](#installation) - [Usage](#usage) - [Using lists](#using-lists) - [Using `Modal`](#using-modal) - [Using `ImageBackground`](#using-imagebackground) - [Components](#components) - [`BlurView`](#blurview) - [Properties](#properties) - [`BlurTarget`](#blurtarget) - [Properties](#properties-1) - [`VibrancyView`](#vibrancyview) - [Properties](#properties-2) - [Types](#types) - [Blur Types](#blur-types) - [Effect Styles](#effect-styles) - [Migrate to 3.x](#migrate-to-3x) - [Why This Change?](#why-this-change) - [Platform Differences](#platform-differences) - [Android](#android) - [iOS](#ios) - [Expo](#expo) - [TypeScript Support](#typescript-support) - [Others Libraries](#others-libraries) - [Contributing](#contributing) - [License](#license) ## Installation ```sh npm install @danielsaraldi/react-native-blur-view # or yarn add @danielsaraldi/react-native-blur-view # or pnpm add @danielsaraldi/react-native-blur-view # or bun add @danielsaraldi/react-native-blur-view ``` Install native dependencies (**iOS only**): ```sh cd ios && pod install && cd .. ``` ## Usage ```tsx import { useRef } from 'react'; import { ScrollView, StyleSheet, Text, View } from 'react-native'; import { BlurView, BlurTarget, VibrancyView, } from '@danielsaraldi/react-native-blur-view'; // ... export default function App() { const targetRef = useRef<View | null>(null); // ... return ( <> <BlurView blurTarget={targetRef} style={styles.blurView}> <Text style={styles.text}>BlurView</Text> </BlurView> <VibrancyView style={styles.vibrancyView}> <Text style={styles.text}>VibrancyView</Text> </VibrancyView> <BlurTarget ref={targetRef} style={styles.blurTarget}> <ScrollView style={styles.scrollView} contentContainerStyle={styles.contentContainer} showsVerticalScrollIndicator={false} > {/* ... */} </ScrollView> </BlurTarget> </> ); } export const styles = StyleSheet.create({ blurView: { position: 'absolute', top: 0, width: '100%', height: 256, justifyContent: 'center', alignItems: 'center', }, vibrancyView: { position: 'absolute', top: 256, width: '100%', height: 256, justifyContent: 'center', alignItems: 'center', }, title: { fontSize: 24, fontWeight: 'bold', color: 'white', }, main: { flex: 1, }, content: { padding: 20, gap: 8, }, }); ``` ### Using lists You must add `BlurView` elements inside of the list, and the content behind should be added as child of the `BlurTarget` component. Check an example using `ScrollView` below: ```tsx import { useRef } from 'react'; import { ImageBackground, ScrollView, Text, View } from 'react-native'; import { BlurView, BlurTarget } from '@danielsaraldi/react-native-blur-view'; // ... export function MyScreen() { const targetRef = useRef<View | null>(null); // ... return ( <View style={styles.container}> <BlurTarget ref={targetRef} style={styles.blurTarget}> <ImageBackground style={styles.background} source={BACKGROUND} resizeMode="cover" /> </BlurTarget> <ScrollView style={styles.scrollView} contentContainerStyle={styles.contentContainer} showsVerticalScrollIndicator={false} > <BlurView blurTarget={targetRef} style={styles.blurView}> <Text style={styles.text}>BlurView 1</Text> </BlurView> <BlurView blurTarget={targetRef} style={styles.blurView}> <Text style={styles.text}>BlurView 2</Text> </BlurView> <BlurView blurTarget={targetRef} style={styles.blurView}> <Text style={styles.text}>BlurView 3</Text> </BlurView> {/* ... */} </ScrollView> </View> ); } ``` ### Using `Modal` You must add `BlurTarget` as a parent of content screen because it will be the **target** of blur, the `BlurView` component must be to used inside of `Modal` to blur effect works correctly. ```tsx import { useRef, useState } from 'react'; import { Modal, View } from 'react-native'; import { BlurTarget, BlurView } from '@danielsaraldi/react-native-blur-view'; // ... export function MyScreen() { const [isOpenModal, setIsOpenModal] = useState<boolean>(false); const targetRef = useRef<View | null>(null); // ... return ( <> <Modal transparent statusBarTranslucent navigationBarTranslucent hardwareAccelerated visible={isOpenModal} onRequestClose={() => setIsOpenModal(false)} style={styles.modal} > <BlurView blurTarget={targetRef} style={styles.blurView} /> <View style={styles.modalContent}>{/* ... */}</View> </Modal> <BlurTarget ref={targetRef} style={styles.blurTarget}> {/* ... */} </BlurTarget> </> ); } ``` ### Using `ImageBackground` You must add `BlurTarget` as a parent of `ImageBackground` because it will be the **target** of blur, the `BlurView` component must be to used as **brother** of `BlurTarget` to blur effect works correctly. ```tsx import { useRef } from 'react'; import { ImageBackground, View } from 'react-native'; import { BlurTarget, BlurView } from '@danielsaraldi/react-native-blur-view'; // ... export function MyScreen() { const targetRef = useRef<View | null>(null); // ... return ( <> <View style={styles.blurViewWrapper}> <BlurView blurTarget={targetRef} style={styles.blurView} downscaleFactor={4} > {/** ... **/} </BlurView> </View> <BlurTarget ref={targetRef} style={styles.blurTarget}> <ImageBackground style={styles.background} source={{ uri: 'https://picsum.photos/seed/picsum/600/900' }} resizeMode="cover" /> </BlurTarget> </> ); } ``` ## Components ### `BlurView` The `BlurView` component is an extends the same properties of the a `View` component. The `blurTarget` prop is **required** for Android blur effect works correctly. #### Properties | Property | Description | Default | Platform | | ---------------------------------- | ------------------------------------------------------------------------------------------- | ----------- | -------- | | `blurTarget` | Ref of the `BlurTarget` component to be identified by the `BlurView` component in the tree. | `undefined` | Android | | `type` | [Blur type](#blur-types) of the overlay. | `light` | All | | `radius` | Blur radius `0` - `100`. | `10.0` | All | | `downscaleFactor` | Downscale factor `0` - `100`. | `6.0` | Android | | `overlayColor` | Add the overlay color about component. | `undefined` | All | | `androidColor` | Overrides the `type` property color. | `undefined` | Android | | `reducedTransparencyFallbackColor` | Background color about blur effect when reduced transparency is enabled. | `white` | iOS | When a value less than `0` or greater than `100` are provided for `radius` or `downscaleFactor` property, the value is clipped. ### `BlurTarget` The `BlurTarget` component is an extends the same properties of the a `View` component. This component is available for **Android only**. It's useful because we use [Dimezis's 3v library](https://github.com/Dimezis/BlurView) to apply the blur effect, so its implementation is slightly different than on iOS. The `BlurTarget` component is a common `View` in iOS. The `BlurTarget` may not contain a `BlurView` that targets the same `BlurTarget`. The `BlurTarget` may contain other `BlurTargets` and `BlurViews` though. #### Properties | Property | Description | Default | Platform | | -------- | ------------------------------------------------------------------------------------------- | ----------- | -------- | | `ref` | Ref of the `BlurTarget` component to be identified by the `BlurView` component in the tree. | `undefined` | Android | ### `VibrancyView` The `VibrancyView` component is an extends the same properties of the a `View` component. This component is available for **iOS only**. It applies a vibrancy effect to child content. On Android, the `VibrancyView` component is a common `View`. The `effectStyle` property **isn't supported** on tvOS. #### Properties | Property | Description | Default | Platform | | ---------------------------------- | ---------------------------------------------------------------------------- | ----------- | -------- | | `type` | [Blur type](#blur-types) of the overlay. | `light` | iOS | | `effectStyle` | [Effect style](#effect-styles) to vibrancy content. | `label` | iOS | | `radius` | Blur radius `0` - `100`. | `10` | iOS | | `overlayColor` | Add the overlay color about component. | `undefined` | iOS | | `reducedTransparencyFallbackColor` | Background color about vibrancy effect when reduced transparency is enabled. | `white` | iOS | When a value less than `0` or greater than `100` are provided for `radius` property, the `radius` is clipped. ## Types These are all types of available. ### Blur Types On iOS all types are supported, but, on Android is simulated the types using RGBA colors. | Property | Description | Platform | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | | `extra-light` | The area of the view is lighter than the underlying view. | All | | `light` | The area of the view is the same approximate lightness of the underlying view. | All | | `dark` | The area of the view is darker than the underlying view. | All | | `extra-dark` | The area of the view is even more dark than the underlying view. (**tvOS >= 10**) | All | | `regular` | A regular blur style that adapts to the user interface style. Radius **doesn't apply** to this. (**iOS >= 10**) | All | | `prominent` | A blur style for making content more prominent that adapts to the user interface style. Radius **doesn't apply** to this. (**iOS >= 10**) | All | | `chrome-material` | An adaptable blur effect that creates the appearance of the system chrome. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `material` | An adaptable blur effect that creates the appearance of a material with normal thickness. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `thick-material` | An adaptable blur effect that creates the appearance of a material that’s thicker than normal. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `thin-material` | An adaptable blur effect that creates the appearance of a thin material. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `ultra-thin-material` | An adaptable blur effect that creates the appearance of an ultra-thin material. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `chrome-material-light` | A blur effect that creates the appearance of the system chrome and is always light. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `material-light` | A blur effect that creates the appearance of a material with normal thickness and is always light. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `thick-material-light` | A blur effect that creates the appearance of a material that’s thicker than normal and is always light. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `thin-material-light` | A blur effect that creates the appearance of a thin material and is always light. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `ultra-thin-material-light` | A blur effect that creates the appearance of an ultra-thin material and is always light. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `chrome-material-dark` | A blur effect that creates the appearance of the system chrome and is always dark. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `material-dark` | A blur effect that creates the appearance of a material with normal thickness and is always dark. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `thick-material-dark` | A blur effect that creates the appearance of a material that’s thicker than normal and is always dark. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `thin-material-dark` | A blur effect that creates the appearance of a thin material and is always dark. Radius **doesn't apply** to this. (**iOS >= 13**) | All | | `ultra-thin-material-dark` | A blur effect that creates the appearance of an ultra-thin material and is always dark. Radius **doesn't apply** to this. (**iOS >= 13**) | All | Learn more about blur types [here](https://developer.apple.com/documentation/uikit/uiblureffect/style). ### Effect Styles On iOS all effect styles are supported. This property is available in the `VibrancyView` component, it's **iOS only**. | Property | Description | Platform | | ------------------ | --------------------------------------------------------------------------------------- | -------- | | `label` | A style for labels containing primary content. (**iOS >= 13**) | iOS | | `secondary-label` | A style for labels containing secondary content. (**iOS >= 13**) | iOS | | `tertiary-label` | A style for labels containing tertiary content. (**iOS >= 13**) | iOS | | `quaternary-label` | A style for labels containing quaternary content. (**iOS >= 13**) | iOS | | `fill` | A style for views with large filled areas containing primary content. (**iOS >= 13**) | iOS | | `secondary-fill` | A style for views with large filled areas containing secondary content. (**iOS >= 13**) | iOS | | `tertiary-fill` | A style for views with large filled areas containing tertiary content. (**iOS >= 13**) | iOS | | `separator` | A style for separator lines. (**iOS >= 13**) | iOS | - Label styles show progressive opacity drops from full white to near-invisible. - Fill styles show translucent rectangles at decreasing opacity levels. - Separator style is specifically for thin, translucent separator lines. Learn more about effect styles [here](https://developer.apple.com/documentation/uikit/uivibrancyeffectstyle). ## Migrate to 3.x > [!WARNING] > Version 3.0.0 introduces significant API changes on Android and iOS applications. If you're upgrading from 2.x, please read this section carefully. In version 3.0.0, the `x-light` blur `type` has been renamed to `extra-light` in the `BlurView` and `VibrancyView` components: ```tsx // ❌ Old API (v2.x) - Deprecated <BlurView blurTarget={targetRef} type='x-light' style={styles.blurView}> {/** ... **/} </BlurView> <VibrancyView blurTarget={targetRef} type='x-light' style={styles.vibrancyView}> {/** ... **/} </VibrancyView> // ✅ New API (v3.0.0) - Current <BlurView blurTarget={targetRef} type='extra-light' style={styles.blurView}> {/** ... **/} </BlurView> <VibrancyView blurTarget={targetRef} type='extra-light' style={styles.vibrancyView}> {/** ... **/} </VibrancyView> ``` A new `type` of blur called `extra-dark` has been added to the `BlurView` and `VibrancyView` components, below is a small example: ```tsx // ✅ New type (v3.0.0) - Current <BlurView blurTarget={targetRef} type="extra-dark" style={styles.blurView}> {/** ... **/} </BlurView> ``` ### Why This Change? This version focused exclusively on full TV device support. The main changes are listed below: - **New support**: Added full support for Android TV and Apple TV. - **Types**: The `BlurView` and `VibrancyView` component types have undergone minor changes: - **Renaming**: Renamed `x-light` to `extra-light`. - **New type**: Added a new `extra-dark` type. - **Runtime**: Bump Node.js version from `20.x` to `22.x`. ## Platform Differences ### Android On Android platforms, the component utilizes the [BlurView](https://github.com/Dimezis/BlurView) library to offer native blur effects with hardware-accelerated rendering. For different types of `extra-light`, `light`, `dark` and `extra-dark`, the `radius` is fixed at `35`. This is done to maintain similarity with the iOS effect. The `androidColor` property can be useful when you want to achieve a specific look or match the blur effect to other elements in your app. It **overrides** the `type` property. Bottom tabs customized with the [`react-navigation/bottom-tabs`](https://reactnavigation.org/docs/bottom-tab-navigator/) **aren't** supported! If you want to customize your bottom tabs, opt for [`@sbaiahmed1/react-native-blur`](https://github.com/sbaiahmed1/react-native-blur). ### iOS On iOS all types are supported by default. However, on Android they are RGBA colors to simulate the same blur color. The `extra-dark` blur type is not natively available on iOS, so it falls back to the `dark` blur type. ### tvOS On tvOS, the blur types `extra-light`, `light`, `dark`, `extra-dark`, `regular`, and `prominent` are supported. Other blur types are accepted by the API but fall back to the `light` blur type on tvOS, since the underlying `UIBlurEffectStyle` values are unavailable. The [effect styles](#effect-styles) **aren't** supported. ## Expo In Expo, you need to convert to a [custom development build](https://docs.expo.dev/develop/development-builds/introduction/) or use [prebuild](https://docs.expo.dev/workflow/continuous-native-generation/). You can use also React Native without Expo. ## TypeScript Support Full TypeScript support with proper type definitions! ```ts import { BlurType, EffectStyle, BlurViewProps, BlurTargetProps, VibrancyProps, } from '@danielsaraldi/react-native-blur-view'; export const INITIAL_BLUR_TYPE: BlurType = 'light'; export const INITIAL_EFFECT_STYLE: EffectStyle = 'label'; export interface CustomBlurViewProps extends BlurViewProps { // ... } export interface CustomBlurTargetProps extends BlurTargetProps { // ... } export interface CustomVibrancyViewProps extends VibrancyProps { // ... } ``` ## Others Libraries - ✅ [`expo-blur`](https://docs.expo.dev/versions/latest/sdk/blur-view/) - A React component that blurs everything underneath the view. Common usage of this is for navigation bars, tab bars, and modals. - ✅ [`@sbaiahmed1/react-native-blur`](https://github.com/sbaiahmed1/react-native-blur) - A modern React Native blur view component that provides native blur effects for both iOS and Android platforms. also adds progressive blur and liquidGlass. - 🛑 [`@react-native-community/blur`](https://github.com/margelo/react-native-blur) - A component for UIVisualEffectView's blur and vibrancy effect on iOS, and BlurView on Android. ## Contributing See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. ## License MIT --- Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob) ❤️