2.0.2 β€’ Published 3 months ago

react-native-inner-shadow v2.0.2

Weekly downloads
-
License
ISC
Repository
github
Last release
3 months ago

react-native-inner-shadow

English | ν•œκ΅­μ–΄

react-native-inner-shadow is a shadow component library that uses React Native Skia to create inset shadows and reflected light (highlight) effects. It supports both solid backgrounds (using ShadowView) and linear gradient backgrounds (using LinearShadowView) for building UIs with inset shadows. Additionally, it provides interactive components that animate press or toggle states using Reanimated.

πŸŽ‰ *New in v2.0.0: Linear gradients and precise border-radius control for all shadow components!*

npm ISC License downloads downloads


  • refactor: optimize layout size state updates in shadow components
  • fix: fix onLayout prop in shadow components
  • Note: For the latest updates and changes, refer to the CHANGELOG

Installation

# Using npm:
npm install react-native-inner-shadow @shopify/react-native-skia react-native-reanimated

# Or using Yarn:
yarn add react-native-inner-shadow @shopify/react-native-skia react-native-reanimated

If you are using Expo, run the following command:

npx expo install react-native-inner-shadow @shopify/react-native-skia react-native-reanimated

❗Important❗ Please ensure that both Skia and Reanimated libraries are correctly installed and configured in your React Native project! For detailed installation instructions, refer to the Skia documentation and the Reanimated installation guide.

Also, add the react-native-reanimated/plugin to your babel.config.js file:

// babel.config.js
module.exports = {
  presets: [
    // Keep your other presets here.
  ],
  plugins: [
    // Your other plugins...
    'react-native-reanimated/plugin',
  ],
};

After installing the dependencies, update the iOS pods by running:

cd ios && bundle exec pod install && cd ..

Table of Contents


Preview


Features

  • 🎨 Customizable inner shadow effects with reflected light
  • 🌈 Support for both solid and linear gradient backgrounds
  • πŸ”„ Smooth press and toggle animations
  • πŸ“± Cross-platform support (iOS & Android)
  • 🎯 TypeScript support with comprehensive type definitions
  • ⚑️ High performance using React Native Skia

Usage Examples

1. Simple Solid ShadowView

import React from 'react';
import { Text, View } from 'react-native';
import { ShadowView } from 'react-native-inner-shadow';

export default function App() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <ShadowView
        inset
        width={120}
        height={120}
        backgroundColor="#f0f0f0"
        style={{ borderRadius: 12, alignItems: 'center', justifyContent: 'center' }}
        shadowColor="#00000066"
        shadowOffset={{ width: 2, height: 2 }}
        shadowBlur={5}
        isReflectedLightEnabled
      >
        <Text style={{ textAlign: 'center', color: '#2f2f2f', fontSize: 14 }}>
          inner-shadow
        </Text>
      </ShadowView>
    </View>
  );
}

2. Linear Gradient & Inset Shadow

import React from 'react';
import { View } from 'react-native';
import { LinearShadowView } from 'react-native-inner-shadow';

export default function GradientExample() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <LinearShadowView
        style={{ width: 150, height: 150, borderRadius: 16 }}
        from="top"
        to="bottom"
        colors={['#FF7A7A', '#FFE08C']}
        shadowColor="#22222299"
        shadowOffset={{ width: 4, height: 4 }}
        shadowBlur={8}
        inset>
        {/* Add your content here */}
      </LinearShadowView>
    </View>
  );
}

ShadowPressable

ShadowPressable is a specialized component that provides a "press in, press out" animation, giving the impression of a real button being pressed.

When pressed, the shadow moves inward (creating an inset effect) and returns to its raised state upon release.

This animation is implemented using both Skia and Reanimated.

Example

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { ShadowPressable } from 'react-native-inner-shadow';

export default function PressableExample() {
  return (
    <View style={styles.container}>
      <ShadowPressable style={styles.button} shadowBlur={7} duration={200} damping={1.2}>
        <Text style={styles.label}>Press Me</Text>
      </ShadowPressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
  button: { width: 120, height: 63, backgroundColor: '#E5A9A9', borderRadius: 12, justifyContent: 'center', alignItems: 'center' },
  label: { fontSize: 14, fontWeight: 'bold', color: '#F4E4BA' },
});

ShadowPressable Props

PropTypeDefaultDescription
widthnumber0Manual width (optional; if a width is defined in the style, that value is used).
heightnumber0Manual height (optional; if a height is defined in the style, that value is used).
initialDepthnumber3@deprecated - Use shadowOffset instead.
shadowSpacenumber6@deprecated - Use shadowOffset instead.
shadowBlurnumber2The blur radius for the main shadow. Adjust this value for softer or sharper shadows.
reflectedLightBlurnumber3The blur radius for the reflected light (highlight).
shadowColorstring'#2F2F2FBC'The color of the main shadow (can be semi-transparent).
reflectedLightColorstring'#FFFFFF8D'The highlight color applied on the opposite side of the main shadow.
durationnumber150Animation duration (in milliseconds) for the press in/out transition.
dampingnumber0.8Controls how deeply the shadow insets when pressed.
isReflectedLightEnabledbooleantrueDetermines whether to render the secondary reflected light shadow.

Behavior

  • Press In: When pressed, the shadow shifts inward (with a negative depth).
  • Release: On release, the shadow returns to its raised (default) state.

ShadowToggle

ShadowToggle is a controlled component that toggles the inset shadow based on an external isActive prop.

  • When isActive is true, the shadow shifts inward.
  • When isActive is false, the shadow remains raised.
  • Optionally, you can provide an activeColor to change the background color when the toggle is active.

When to Use

  • Use this component for toggle or switch style buttons where the pressed state is controlled externally.
  • It is ideal when you want to visually indicate an active/inactive state with both an inset shadow and a background color change.

Simple Example

import React, { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { ShadowToggle } from 'react-native-inner-shadow';

export default function ToggleExample() {
  const [isActive, setIsActive] = useState(false);

  return (
    <View style={styles.container}>
      <ShadowToggle
        style={styles.toggle}
        isActive={isActive}
        activeColor="#FFD700"
        onPress={() => setIsActive(prev => !prev)}>
        <Text style={[ styles.label, { color: isActive ? '#515050' : '#eeebeb' } ]}>
          {isActive ? 'ON' : 'OFF'}
        </Text>
      </ShadowToggle>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
  toggle: { width: '30%', aspectRatio: 1.7, borderRadius: 12, backgroundColor: '#06d6a0', justifyContent: 'center', alignItems: 'center' },
  label: { fontWeight: 'bold' },
});

Key Props

PropTypeDefaultDescription
isActivebooleanfalseDetermines the active state of the toggle. true shows an inset shadow, false shows a raised shadow.
activeColorstringnullSets the background color when isActive is true.
widthnumber0Manual width (optional; if a width is defined in the style, that value is used).
heightnumber0Manual height (optional; if a height is defined in the style, that value is used).
initialDepthnumber3@deprecated - Use shadowOffset instead.
shadowSpacenumber6@deprecated - Use shadowOffset instead.
shadowBlurnumber2The blur radius for the main shadow. Adjust this value for softer or sharper shadows.
reflectedLightBlurnumber3The blur radius for the reflected light (highlight).
shadowColorstring'#2F2F2FBC'The color of the main shadow (can be semi-transparent).
reflectedLightColorstring'#FFFFFF8D'The highlight color applied on the opposite side of the main shadow.
durationnumber150Animation duration (in milliseconds) for the press in/out transition.
dampingnumber0.8Controls how deeply the shadow insets when pressed.
isReflectedLightEnabledbooleantrueDetermines whether to render the secondary reflected light shadow.

Behavior

  • When isActive is true, the shadow transitions to an inset state (negative depth).
  • When isActive is false, the shadow returns to its raised state.
  • If provided, the activeColor will be applied when the toggle is active, changing the background color.

Notes

  • Controlled vs. Uncontrolled: It is recommended to control isActive via state (e.g., using useState) and pass it down as a prop. Alternatively, an internal state can be implemented if needed.
  • Performance Consideration: When rendering many toggle components, especially on lower-end devices, test performance carefully. Fixed width and height values can help avoid excessive re-measurements.

API Specification

This library provides multiple components for creating inset and toggleable shadows.

Components

  1. ShadowView A simple component for solid backgrounds that extends ShadowViewProps.
  2. LinearShadowView A component for gradient backgrounds. It extends InnerShadowProps by adding gradient fields (from, to, colors).
  3. ShadowPressable A pressable component with animated press effects.
  4. ShadowToggle A controlled component that toggles the inset shadow based on the isActive prop.

Constants

This library includes a set of default constants (fallback colors, blur values, etc.) defined in the src/constants.ts file. These constants can be modified if needed.

ConstantDescription
BACKGROUND_COLORDefault background color (#FFFFFF).
INITIAL_DEPTHThe initial depth value for controlling the shadow effect (3).
SHADOW_SPACEExtra space between the element and its shadow (6).
SHADOW_BLURThe blur radius for the main shadow; set to 2 to achieve a softer effect.
REFLECTED_LIGHT_BLURThe blur radius for the reflected light (highlight) effect (3).
SHADOW_COLORThe main shadow color (#2F2F2FBC).
REFLECTED_LIGHT_COLORThe color used for the reflected light or highlight (#EEE9E92D).
DAMPING_DURATIONDuration (in milliseconds) for the bounce animation when a button is pressed (200).
DAMPING_RATIOThe ratio controlling the strength of the bounce effect (0.8).
IS_REFLECTED_LIGHT_ENABLEDFlag indicating whether the reflected light effect is enabled (true).
SHADOW_OFFSET_SCALEScale factor for the default shadow offset (default is 2).
REFLECTED_LIGHT_OFFSET_SCALEScale factor for the reflected light offset (default is 2).
COMMON_STYLESPredefined styles for the canvas and its wrapper. This ensures that the canvas is correctly positioned (with position: absolute) based on the parent's width and height, and that the background is handled properly.

Note & Tip

  1. Reflected Light (Highlight)

    • When inset is true, isReflectedLightEnabled is set to true by default. If the highlight effect appears too strong or too weak, adjust the reflectedLightColor and reflectedLightOffset values to achieve the desired look.
  2. Performance Optimization

    • Each shadow component uses a Skia <Canvas>. For best performance, especially when the layout is fixed, specify fixed width and height values to avoid unnecessary re-measurements.
  3. Testing

    • When rendering many shadow or toggle components in a list, ensure they work smoothly on lower-end devices. While Skia and Reanimated are generally efficient, performance may drop if many elements without fixed layout sizes are rendered.
  4. Version Conflicts

    • This library depends on both Skia and Reanimated. Ensure that the versions of these libraries are compatible with your React Native environment. If you see errors like "react-native-reanimated is not installed!" move the package to your project's peerDependencies and install it at the root.

Enjoy building immersive, 3D-like UI components with react-native-inner-shadow. If you have suggestions, bug reports, or would like to contribute, please open an issue or submit a pull request!

2.0.2

3 months ago

2.0.1

4 months ago

2.0.0

4 months ago

1.3.1

4 months ago

1.3.0

4 months ago

1.2.5

4 months ago

1.2.4

4 months ago

1.2.3

4 months ago

1.2.1

4 months ago

1.2.0

4 months ago

1.1.2

5 months ago

1.1.1

5 months ago

1.1.0

5 months ago

1.0.0

5 months ago

0.5.1

5 months ago

0.4.1

5 months ago

0.4.0

5 months ago

0.3.4

5 months ago

0.3.3

5 months ago

0.3.2

5 months ago

0.3.1

5 months ago

0.3.0

5 months ago

0.2.3

5 months ago

0.2.2

5 months ago

0.2.1

5 months ago

0.2.0

5 months ago

0.1.1

5 months ago

0.0.1

5 months ago