UNPKG

@whitemordred/react-native-bootstrap5

Version:

A complete React Native library that replicates Bootstrap 5.3 with 100% feature parity, full theming support, CSS variables, and dark/light mode

231 lines (229 loc) 9.29 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; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Dropdown = exports.DropdownItem = exports.DropdownMenu = exports.DropdownToggle = void 0; const react_1 = __importStar(require("react")); const react_native_1 = require("react-native"); const ThemeProvider_1 = require("../theme/ThemeProvider"); const DropdownToggle = ({ children, onPress, disabled = false, style, variant = 'secondary', size, }) => { const { theme } = (0, ThemeProvider_1.useTheme)(); const getVariantStyles = () => { const variantColors = theme.colors[variant]; const backgroundColor = typeof variantColors === 'string' ? variantColors : (variantColors === null || variantColors === void 0 ? void 0 : variantColors[500]) || theme.colors.secondary; return { backgroundColor: disabled ? theme.colors.light : backgroundColor, borderColor: backgroundColor, }; }; const getSizeStyles = () => { switch (size) { case 'sm': return { paddingHorizontal: 8, paddingVertical: 4, fontSize: 14 }; case 'lg': return { paddingHorizontal: 16, paddingVertical: 12, fontSize: 18 }; default: return { paddingHorizontal: 12, paddingVertical: 8, fontSize: 16 }; } }; return (<react_native_1.TouchableOpacity onPress={onPress} disabled={disabled} style={[ styles.dropdownToggle, getVariantStyles(), getSizeStyles(), disabled && styles.disabled, style, ]}> {typeof children === 'string' ? (<react_native_1.Text style={[styles.toggleText, { color: theme.colors.white }]}> {children} </react_native_1.Text>) : (children)} <react_native_1.Text style={[styles.caret, { color: theme.colors.white }]}></react_native_1.Text> </react_native_1.TouchableOpacity>); }; exports.DropdownToggle = DropdownToggle; const DropdownMenu = ({ children, visible, onRequestClose, style, }) => { const { theme } = (0, ThemeProvider_1.useTheme)(); return (<react_native_1.Modal visible={visible} transparent animationType="fade" onRequestClose={onRequestClose}> <react_native_1.TouchableOpacity style={styles.overlay} onPress={onRequestClose}> <react_native_1.View style={[styles.menu, { backgroundColor: theme.colors.white }, style]}> {children} </react_native_1.View> </react_native_1.TouchableOpacity> </react_native_1.Modal>); }; exports.DropdownMenu = DropdownMenu; const DropdownItem = ({ children, onPress, disabled = false, divider = false, style, textStyle, }) => { const { theme } = (0, ThemeProvider_1.useTheme)(); if (divider) { return (<react_native_1.View style={[styles.divider, { borderBottomColor: theme.colors.light }]}/>); } return (<react_native_1.TouchableOpacity onPress={onPress} disabled={disabled} style={[ styles.menuItem, disabled && styles.disabledItem, style, ]}> <react_native_1.Text style={[ styles.menuItemText, { color: disabled ? theme.colors.gray[500] : theme.colors.dark }, textStyle, ]}> {children} </react_native_1.Text> </react_native_1.TouchableOpacity>); }; exports.DropdownItem = DropdownItem; const Dropdown = ({ items, value, placeholder = 'Select an option', onSelect, disabled = false, variant = 'secondary', size, style, dropdownStyle, children, }) => { const [isOpen, setIsOpen] = (0, react_1.useState)(false); const { theme } = (0, ThemeProvider_1.useTheme)(); const selectedItem = items.find(item => item.value === value); const handleToggle = () => { if (!disabled) { setIsOpen(!isOpen); } }; const handleSelect = (item) => { if (!item.disabled) { onSelect === null || onSelect === void 0 ? void 0 : onSelect(item); setIsOpen(false); } }; if (children) { return (<react_native_1.View style={[styles.dropdown, style]}> {react_1.default.Children.map(children, child => { if (react_1.default.isValidElement(child) && child.type === exports.DropdownToggle) { return react_1.default.cloneElement(child, { onPress: handleToggle, disabled, variant, size, }); } if (react_1.default.isValidElement(child) && child.type === exports.DropdownMenu) { return react_1.default.cloneElement(child, { visible: isOpen, onRequestClose: () => setIsOpen(false), }); } return child; })} </react_native_1.View>); } return (<react_native_1.View style={[styles.dropdown, style]}> <react_native_1.TouchableOpacity onPress={handleToggle} disabled={disabled} style={[ styles.dropdownToggle, { backgroundColor: theme.colors.white, borderColor: theme.colors.light, borderWidth: 1, }, disabled && styles.disabled, ]}> <react_native_1.Text style={[styles.toggleText, { color: theme.colors.dark }]}> {selectedItem ? selectedItem.label : placeholder} </react_native_1.Text> <react_native_1.Text style={[styles.caret, { color: theme.colors.dark }]}> {isOpen ? '▲' : '▼'} </react_native_1.Text> </react_native_1.TouchableOpacity> <react_native_1.Modal visible={isOpen} transparent animationType="fade" onRequestClose={() => setIsOpen(false)}> <react_native_1.TouchableOpacity style={styles.overlay} onPress={() => setIsOpen(false)}> <react_native_1.View style={[styles.menu, dropdownStyle, { backgroundColor: theme.colors.white }]}> <react_native_1.FlatList data={items} keyExtractor={(item, index) => `${item.value}-${index}`} renderItem={({ item }) => (<exports.DropdownItem onPress={() => handleSelect(item)} disabled={item.disabled} divider={item.divider} children={item.label}/>)}/> </react_native_1.View> </react_native_1.TouchableOpacity> </react_native_1.Modal> </react_native_1.View>); }; exports.Dropdown = Dropdown; const styles = react_native_1.StyleSheet.create({ dropdown: { position: 'relative', }, dropdownToggle: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 12, paddingVertical: 8, borderRadius: 4, minHeight: 40, }, toggleText: { fontSize: 16, flex: 1, }, caret: { fontSize: 12, marginLeft: 8, }, disabled: { opacity: 0.6, }, overlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'center', alignItems: 'center', }, menu: { minWidth: 200, maxWidth: react_native_1.Dimensions.get('window').width * 0.8, maxHeight: react_native_1.Dimensions.get('window').height * 0.6, borderRadius: 4, elevation: 5, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, }, menuItem: { paddingHorizontal: 16, paddingVertical: 12, borderBottomWidth: react_native_1.StyleSheet.hairlineWidth, borderBottomColor: '#e9ecef', }, menuItemText: { fontSize: 16, }, disabledItem: { opacity: 0.6, }, divider: { height: 1, borderBottomWidth: 1, marginVertical: 4, }, }); exports.default = exports.Dropdown;