UNPKG

@gradient-border/react-native-gradient-button

Version:

A powerful React Native gradient button component with support for gradient borders, text, and customizable styles. Perfect for creating beautiful, modern UI elements with minimal effort.

199 lines (198 loc) 9.3 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var react_1 = __importStar(require("react")); var react_native_1 = require("react-native"); var masked_view_1 = __importDefault(require("@react-native-masked-view/masked-view")); var react_native_linear_gradient_1 = __importDefault(require("react-native-linear-gradient")); /** * A customizable gradient button component for React Native * * @example * ```tsx * <GradientButton * text="Submit" * onPress={() => console.log('pressed')} * colors={['#FF0000', '#00FF00']} * style={{ borderRadius: 8 }} * /> * ``` * * @property {string} text - The text to display on the button * @property {() => void} onPress - Function to call when button is pressed * @property {string[]} colors - Array of at least 2 colors for the gradient * @property {StyleProp<ViewStyle>} [style] - Optional styles for the button * @property {StyleProp<TextStyle>} [textStyle] - Optional styles for the button text * ... */ var GradientButton = function (_a) { var // Required props text = _a.text, colors = _a.colors, onPress = _a.onPress, // Optional props style = _a.style, textStyle = _a.textStyle, _b = _a.loading, loading = _b === void 0 ? false : _b, _c = _a.loadingColor, loadingColor = _c === void 0 ? '#FFFFFF' : _c, _d = _a.loadingSize, loadingSize = _d === void 0 ? 'small' : _d, // LinearGradient props _e = _a.start, // LinearGradient props start = _e === void 0 ? { x: 0, y: 0 } : _e, _f = _a.end, end = _f === void 0 ? { x: 1, y: 0 } : _f, locations = _a.locations, _g = _a.useAngle, useAngle = _g === void 0 ? false : _g, _h = _a.angle, angle = _h === void 0 ? 0 : _h, angleCenter = _a.angleCenter, // TouchableOpacity props _j = _a.disabled, // TouchableOpacity props disabled = _j === void 0 ? false : _j, _k = _a.activeOpacity, activeOpacity = _k === void 0 ? 0.7 : _k, // Accessibility props _l = _a.accessibilityRole, // Accessibility props accessibilityRole = _l === void 0 ? 'button' : _l, accessibilityLabel = _a.accessibilityLabel, accessibilityHint = _a.accessibilityHint, touchableProps = __rest(_a, ["text", "colors", "onPress", "style", "textStyle", "loading", "loadingColor", "loadingSize", "start", "end", "locations", "useAngle", "angle", "angleCenter", "disabled", "activeOpacity", "accessibilityRole", "accessibilityLabel", "accessibilityHint"]); if (!text) { throw new Error('GradientButton: text prop is required'); } if (!colors || !Array.isArray(colors) || colors.length < 2) { throw new Error('GradientButton: colors prop is required and must be an array of at least 2 colors'); } // Validate color format colors.forEach(function (color, index) { if (typeof color !== 'string') { throw new Error("GradientButton: colors[".concat(index, "] must be a string")); } }); // Add validation for textStyle color properties if (textStyle && typeof textStyle === 'object') { var textStyleObj_1 = textStyle; var restrictedTextProps = [ 'color', 'textDecorationColor', 'textShadowColor' ]; restrictedTextProps.forEach(function (prop) { if (prop in textStyleObj_1) { console.warn("GradientButton: \"".concat(prop, "\" in textStyle prop is not allowed.")); delete textStyleObj_1[prop]; } }); } // Utility function to split and filter styles var splitStyle = function (style) { var outerStyle = {}; var innerStyle = {}; if (style && typeof style === 'object' && !Array.isArray(style)) { // Type assertion to handle ViewStyle indexing var styleObj = style; Object.entries(styleObj).forEach(function (_a) { var key = _a[0], value = _a[1]; if (['backgroundColor', 'borderColor', 'shadowColor', 'color'].includes(key)) { console.warn("The property \"".concat(key, "\" is not allowed in the style prop.")); } else if ([ 'width', 'height', 'margin', 'marginTop', 'marginBottom', 'marginLeft', 'marginRight', 'marginHorizontal', 'marginVertical', 'padding', 'paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight', 'paddingHorizontal', 'paddingVertical', ].includes(key)) { outerStyle[key] = value; } else { innerStyle[key] = value; } }); } return { outerStyle: outerStyle, innerStyle: innerStyle }; }; var _m = splitStyle(style), outerStyle = _m.outerStyle, innerStyle = _m.innerStyle; var _o = (0, react_1.useState)(0), Height = _o[0], setHeight = _o[1]; var st = styles(Height / 10); return (<react_native_1.View style={outerStyle}> <react_native_1.TouchableOpacity onPress={onPress} disabled={disabled || loading} activeOpacity={activeOpacity} accessibilityRole={accessibilityRole} accessibilityLabel={accessibilityLabel || text} accessibilityHint={accessibilityHint} {...touchableProps} style={st.button}> <react_native_1.View style={st.buttonContent}> <masked_view_1.default maskElement={<react_native_1.View pointerEvents="none" style={[st.maskContainer, innerStyle]} collapsable={false}> {loading ? (<react_native_1.ActivityIndicator color={loadingColor} size={loadingSize}/>) : (<react_native_1.Text style={[st.buttonText, textStyle]}> {text} </react_native_1.Text>)} </react_native_1.View>} style={react_native_1.StyleSheet.absoluteFill} pointerEvents="none"> <react_native_linear_gradient_1.default style={react_native_1.StyleSheet.absoluteFill} pointerEvents="none" colors={colors} start={start} end={end} locations={locations} useAngle={useAngle} angle={angle} angleCenter={angleCenter}/> </masked_view_1.default> </react_native_1.View> </react_native_1.TouchableOpacity> </react_native_1.View>); }; var styles = function (height) { return react_native_1.StyleSheet.create({ button: { width: '100%', }, buttonContent: { width: '100%', //should not be changed height: '100%', //should not be changed }, maskContainer: { width: '100%', //should not be changed height: '100%', //should not be changed padding: height / 10, }, innerButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, buttonText: { color: '#000000', // required for the gradient to work textShadowColor: '#000000', // required for the gradient shadow to work }, }); }; exports.default = GradientButton;