update
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
|
||||
import { AnimatableNumericValue, StyleSheet, View } from "react-native";
|
||||
import { LinearGradientProps } from "../../LinearGradient/LinearGradient";
|
||||
import MaskedView from "../../MaskedView/MaskedView";
|
||||
import LinearGradient from "react-native-linear-gradient";
|
||||
|
||||
|
||||
export type GradientProps = Omit<
|
||||
LinearGradientProps,
|
||||
"style" | "pointerEvents">;
|
||||
|
||||
|
||||
export type RequiredGradientBorderProps = {
|
||||
/**
|
||||
* Props to be passed to the gradient component. See `react-native-linear-gradient` for full list. Requires "colors" prop.
|
||||
*/
|
||||
gradientProps: GradientProps;
|
||||
};
|
||||
|
||||
type BorderProps = {
|
||||
/**
|
||||
* Width of border.
|
||||
*/
|
||||
borderWidth?: number;
|
||||
|
||||
/**
|
||||
* Border applied to top of view, overrides borderWidth.
|
||||
*/
|
||||
borderTopWidth?: number;
|
||||
/**
|
||||
* Border applied to left side of view, overrides borderWidth.
|
||||
*/
|
||||
borderLeftWidth?: number;
|
||||
|
||||
/**
|
||||
* Border applied to bottom side of view, overrides borderWidth.
|
||||
*/
|
||||
borderBottomWidth?: number;
|
||||
|
||||
/**
|
||||
* Border appled to right side of view, overrides borderWidth.
|
||||
*/
|
||||
borderRightWidth?: number;
|
||||
/**
|
||||
* Border radius applied to each corner.
|
||||
*/
|
||||
borderRadius?: AnimatableNumericValue | string | undefined;
|
||||
/**
|
||||
* Border radius applied to top right corner, Overrides borderRadius.
|
||||
*/
|
||||
borderTopRightRadius?: AnimatableNumericValue | string | undefined;
|
||||
/**
|
||||
* Border radius applied to top left corner. Overrides borderRadius
|
||||
*/
|
||||
borderTopLeftRadius?: AnimatableNumericValue | string | undefined;
|
||||
/**
|
||||
* Border radius applied to bottom right corner. Overrides borderRadius
|
||||
*/
|
||||
borderBottomRightRadius?: AnimatableNumericValue | string | undefined;
|
||||
/**
|
||||
* Border radius applied to bottom left corner. Overrides borderRadius
|
||||
*/
|
||||
borderBottomLeftRadius?: AnimatableNumericValue | string | undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* A component that applies a gradient border to the parent.
|
||||
* Should be placed as the last child of the parent so that it isn't overlapped.
|
||||
* @example
|
||||
* ```tsx
|
||||
* <View>
|
||||
* <GradientBorder
|
||||
* borderWidth={2}
|
||||
* gradientProps={{
|
||||
* colors: ['red', 'blue']
|
||||
* }}
|
||||
* />
|
||||
* </View>
|
||||
* ```
|
||||
*/
|
||||
export default function GradientBorder({
|
||||
gradientProps,
|
||||
borderWidth,
|
||||
borderRadius,
|
||||
borderTopRightRadius,
|
||||
borderTopLeftRadius,
|
||||
borderBottomLeftRadius,
|
||||
borderBottomRightRadius,
|
||||
borderTopWidth,
|
||||
borderLeftWidth,
|
||||
borderRightWidth,
|
||||
borderBottomWidth
|
||||
}: RequiredGradientBorderProps & BorderProps) {
|
||||
return (
|
||||
<MaskedView
|
||||
maskElement={
|
||||
<View
|
||||
pointerEvents="none"
|
||||
style={[
|
||||
{
|
||||
borderWidth,
|
||||
borderRadius,
|
||||
borderTopLeftRadius,
|
||||
borderTopRightRadius,
|
||||
borderBottomLeftRadius,
|
||||
borderBottomRightRadius,
|
||||
borderTopWidth,
|
||||
borderLeftWidth,
|
||||
borderRightWidth,
|
||||
borderBottomWidth
|
||||
},
|
||||
StyleSheet.absoluteFill]
|
||||
}
|
||||
collapsable={false} />
|
||||
|
||||
}
|
||||
style={[StyleSheet.absoluteFill]}
|
||||
pointerEvents="none">
|
||||
|
||||
<LinearGradient
|
||||
style={StyleSheet.absoluteFill}
|
||||
pointerEvents="none"
|
||||
{...gradientProps} />
|
||||
|
||||
</MaskedView>);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import {
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
View,
|
||||
ViewProps,
|
||||
ViewStyle,
|
||||
} from "react-native";
|
||||
import GradientBorder, { RequiredGradientBorderProps } from "./GradientBorder";
|
||||
import omit from "lodash/omit";
|
||||
|
||||
type GradientBorderViewProps = Omit<
|
||||
ViewStyle,
|
||||
| "paddingLeft"
|
||||
| "paddingRight"
|
||||
| "paddingTop"
|
||||
| "paddingBottom"
|
||||
| "padding"
|
||||
| "borderColor"
|
||||
| "borderLeftColor"
|
||||
| "borderRightColor"
|
||||
| "borderTopColor"
|
||||
| "borderBottomColor"
|
||||
>;
|
||||
|
||||
export type GradientBorderViewStyle = StyleProp<
|
||||
GradientBorderViewProps & {
|
||||
paddingLeft?: number;
|
||||
paddingRight?: number;
|
||||
paddingTop?: number;
|
||||
paddingBottom?: number;
|
||||
padding?: number;
|
||||
}
|
||||
>;
|
||||
|
||||
/**
|
||||
* A view that applies a gradient border. `gradientProps` is required and can be used to control the gradient (react-native-linear-gradient props),
|
||||
* and `borderWidth` is required. See
|
||||
* @example
|
||||
* <GradientBorderView
|
||||
* style={{borderWidth: 50, height: 100, width: 100,}}
|
||||
* gradientProps={{
|
||||
* colors: ['red', 'blue']
|
||||
* }}
|
||||
* />
|
||||
*/
|
||||
export const GradientBorderView = ({
|
||||
gradientProps,
|
||||
...props
|
||||
}: Omit<ViewProps, "style"> & {
|
||||
style?: GradientBorderViewStyle;
|
||||
} & RequiredGradientBorderProps) => {
|
||||
const styles = StyleSheet.flatten(props.style);
|
||||
const userAllPadding = styles.padding ? styles.padding : 0;
|
||||
const compensationAllPadding = styles.borderWidth ? styles.borderWidth : 0;
|
||||
function calcPaddingForSide(
|
||||
paddingName:
|
||||
| "paddingLeft"
|
||||
| "paddingRight"
|
||||
| "paddingTop"
|
||||
| "paddingBottom",
|
||||
borderWidthName:
|
||||
| "borderTopWidth"
|
||||
| "borderBottomWidth"
|
||||
| "borderLeftWidth"
|
||||
| "borderRightWidth"
|
||||
) {
|
||||
const userPadding =
|
||||
typeof styles[paddingName] !== "undefined"
|
||||
? styles[paddingName]!
|
||||
: userAllPadding;
|
||||
const compensationPadding =
|
||||
typeof styles[borderWidthName] !== "undefined"
|
||||
? styles[borderWidthName]!
|
||||
: compensationAllPadding;
|
||||
return compensationPadding + userPadding;
|
||||
}
|
||||
|
||||
if (
|
||||
__DEV__ &&
|
||||
!(
|
||||
styles.borderWidth ||
|
||||
styles.borderTopWidth ||
|
||||
styles.borderLeftWidth ||
|
||||
styles.borderRightWidth ||
|
||||
styles.borderBottomWidth
|
||||
)
|
||||
) {
|
||||
console.warn(
|
||||
"No borderWidth was passed in the GradientBorderView style, no border will be shown."
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
{...props}
|
||||
style={[
|
||||
{
|
||||
paddingLeft: calcPaddingForSide("paddingLeft", "borderLeftWidth"),
|
||||
paddingRight: calcPaddingForSide("paddingRight", "borderRightWidth"),
|
||||
paddingBottom: calcPaddingForSide(
|
||||
"paddingBottom",
|
||||
"borderBottomWidth"
|
||||
),
|
||||
paddingTop: calcPaddingForSide("paddingTop", "borderTopWidth"),
|
||||
},
|
||||
omit(styles, [
|
||||
"borderWidth",
|
||||
"borderTopWidth",
|
||||
"borderLeftWidth",
|
||||
"borderRightWidth",
|
||||
"borderBottomWidth",
|
||||
]),
|
||||
]}
|
||||
>
|
||||
{props.children}
|
||||
<GradientBorder
|
||||
gradientProps={gradientProps}
|
||||
borderRadius={styles.borderRadius}
|
||||
borderWidth={styles.borderWidth}
|
||||
borderBottomWidth={styles.borderBottomWidth}
|
||||
borderRightWidth={styles.borderRightWidth}
|
||||
borderLeftWidth={styles.borderLeftWidth}
|
||||
borderTopWidth={styles.borderTopWidth}
|
||||
borderTopLeftRadius={styles.borderTopLeftRadius}
|
||||
borderTopRightRadius={styles.borderTopRightRadius}
|
||||
borderBottomRightRadius={styles.borderBottomRightRadius}
|
||||
borderBottomLeftRadius={styles.borderBottomLeftRadius}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import {
|
||||
GradientBorderView,
|
||||
GradientBorderViewStyle,
|
||||
} from "./components/GradientBorderView";
|
||||
import { GradientProps } from "./components/GradientBorder";
|
||||
|
||||
export { GradientBorderView };
|
||||
export type { GradientBorderViewStyle, GradientProps as GP };
|
||||
Reference in New Issue
Block a user