react-native-inner-shadow
Version:
react native inner shadows with linear gradient design UI
168 lines (164 loc) • 5.43 kB
JavaScript
"use strict";
import React, { memo } from 'react';
import { Pressable, View } from 'react-native';
import { Canvas, Shadow } from '@shopify/react-native-skia';
import Animated, { interpolateColor, useAnimatedReaction, useDerivedValue, withTiming } from 'react-native-reanimated';
import { CANVAS_PADDING, COMMON_STYLES, DAMPING_DURATION, DAMPING_RATIO, INITIAL_DEPTH, IS_REFLECTED_LIGHT_ENABLED } from "../constants.js";
import { isLinearProps } from "../utils.js";
import LinearGradientFill from "./shapes/ShadowLinearGradientFill.js";
import { useAnimatedOffset } from "../hooks/useAnimatedOffset.js";
import { CornerRadii } from "./shapes/CornerRadii.js";
import { useShadowProperties } from "../hooks/useShadowProperties.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const PressButton = Animated.createAnimatedComponent(Pressable);
export const UnifiedShadowToggle = /*#__PURE__*/memo(function ShadowToggle({
width: propWidth,
height: propHeight,
isActive = false,
activeColor,
duration = DAMPING_DURATION,
damping = DAMPING_RATIO,
isReflectedLightEnabled = IS_REFLECTED_LIGHT_ENABLED,
style,
children,
onLayout: propsOnLayout,
...props
}) {
const {
flatStyle,
bgColor,
shadowProps,
layout,
canRenderCanvas,
onLayout
} = useShadowProperties({
propWidth,
propHeight,
style,
propsOnLayout,
...props
});
const isLinear = isLinearProps(props);
const {
depth,
inset,
offset,
reflectedLightOffset,
blurRadius,
PressedAnimatedStyle
} = useAnimatedOffset({
offset: shadowProps.shadowOffset,
reflectedLightOffset: shadowProps.reflectedLightOffset,
blurRadius: shadowProps.shadowBlur,
damping,
duration,
onPressIn: props.onPressIn,
onPressOut: props.onPressOut
});
const animatedBackgroundColor = useDerivedValue(() => interpolateColor(depth.value, [INITIAL_DEPTH, -INITIAL_DEPTH * damping], [bgColor, activeColor || bgColor]));
useAnimatedReaction(() => isActive, next => {
depth.value = withTiming(next ? -INITIAL_DEPTH * damping : INITIAL_DEPTH, {
duration
});
}, [isActive]);
return /*#__PURE__*/_jsxs(View, {
onLayout: onLayout,
style: [flatStyle, COMMON_STYLES.canvasContainer],
children: [canRenderCanvas && /*#__PURE__*/_jsx(Canvas, {
style: [COMMON_STYLES.canvas, {
width: layout.width + CANVAS_PADDING * 2,
height: layout.height + CANVAS_PADDING * 2
}],
children: /*#__PURE__*/_jsxs(CornerRadii, {
width: layout.width,
height: layout.height,
style: flatStyle,
backgroundColor: animatedBackgroundColor,
children: [isLinear && /*#__PURE__*/_jsx(LinearGradientFill, {
...props,
// from, to, colors, etc.
width: layout.width,
height: layout.height
}), /*#__PURE__*/_jsx(Shadow, {
dx: offset.dx,
dy: offset.dy,
blur: blurRadius,
color: shadowProps.shadowColor,
inner: inset
}), isReflectedLightEnabled && /*#__PURE__*/_jsx(Shadow, {
dx: reflectedLightOffset.dx,
dy: reflectedLightOffset.dy,
blur: blurRadius,
color: shadowProps.reflectedLightColor,
inner: true
})]
})
}), /*#__PURE__*/_jsx(PressButton, {
...props,
// eslint-disable-next-line react-native/no-inline-styles
style: [{
zIndex: 1
}, flatStyle, COMMON_STYLES.canvasWrapper],
children: /*#__PURE__*/_jsx(Animated.View, {
style: PressedAnimatedStyle,
children: children
})
})]
});
});
/**
* ShadowToggle
* ----------------
* A toggle component that casts a shadow when active.
* The shadow effect is created using the `@shopify/react-native-skia` library.
*
* @param isActive - Whether the shadow is active
* @param activeColor - The color of the shadow when active
*/
export const ShadowToggle = UnifiedShadowToggle;
/**
* LinearShadowToggle
* ----------------
* A toggle component that casts a linear gradient shadow when active.
* The shadow effect is created using the `@shopify/react-native-skia` library.
*
* @param isActive - Whether the shadow is active
* @param activeColor - The color of the shadow when active
* @param colors - The colors of the linear gradient
* @param from - The direction of the linear gradient, default is 'top'
* @param to - The direction of the linear gradient, default is 'bottom'
*/
export const LinearShadowToggle = ({
from = 'top',
to = 'bottom',
...props
}) => /*#__PURE__*/_jsx(UnifiedShadowToggle, {
from: from,
to: to,
...props
});
/**
* RadialShadowToggle
* ----------------
* A toggle component that casts a radial gradient shadow when active.
* The shadow effect is created using the `@shopify/react-native-skia` library.
*
* @param isActive - Whether the shadow is active
* @param activeColor - The color of the shadow when active
* @param colors - The colors of the radial gradient
* @param center - The center of the radial gradient, default is { x: 0.5, y: 0.5 }
* @param radius - The radius of the radial gradient, default is 0.5
*/
export const RadialShadowToggle = ({
center = {
x: 0.5,
y: 0.5
},
radius = 0.5,
...props
}) => /*#__PURE__*/_jsx(UnifiedShadowToggle, {
center: center,
radius: radius,
...props
});
//# sourceMappingURL=ShadowToggle.js.map