@danielsaraldi/react-native-blur-view
Version:
A simple blur view in react native
515 lines (393 loc) • 23.2 kB
Markdown
# `@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) ❤️