@oxyhq/services
Version:
Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀
370 lines (368 loc) • 10.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactNative = require("react-native");
var _vectorIcons = require("@expo/vector-icons");
var _OxyIcon = _interopRequireDefault(require("./icon/OxyIcon"));
var _fonts = require("../styles/fonts");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const Header = ({
title,
subtitle,
onBack,
onClose,
rightAction,
rightActions,
theme,
showBackButton = true,
showCloseButton = false,
variant = 'default',
elevation = 'subtle',
subtitleVariant = 'default',
titleAlignment = 'left'
}) => {
const isDarkTheme = theme === 'dark';
// Modern color palette
const colors = {
background: isDarkTheme ? '#1C1C1E' : '#FFFFFF',
surface: isDarkTheme ? '#2C2C2E' : '#F8F9FA',
primary: '#007AFF',
secondary: isDarkTheme ? '#8E8E93' : '#6C757D',
text: {
primary: isDarkTheme ? '#FFFFFF' : '#1A1A1A',
secondary: isDarkTheme ? '#8E8E93' : '#6C757D',
tertiary: isDarkTheme ? '#636366' : '#ADB5BD'
},
border: isDarkTheme ? '#38383A' : '#E9ECEF',
accent: '#5856D6',
success: '#34C759',
warning: '#FF9500',
error: '#FF3B30'
};
const renderBackButton = () => {
if (!showBackButton || !onBack) return null;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
style: [styles.backButton, {
backgroundColor: colors.surface
}],
onPress: onBack,
activeOpacity: 0.7,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_OxyIcon.default, {
name: "chevron-back",
size: 18,
color: colors.primary
})
});
};
const renderCloseButton = () => {
if (!showCloseButton || !onClose) return null;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
style: [styles.closeButton, {
backgroundColor: colors.surface
}],
onPress: onClose,
activeOpacity: 0.7,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: "close",
size: 18,
color: colors.text.primary
})
});
};
const renderRightActionButton = (action, idx) => {
const isTextAction = action.text;
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
style: [styles.rightActionButton, isTextAction ? styles.textActionButton : styles.iconActionButton, {
backgroundColor: isTextAction ? colors.primary : colors.surface,
opacity: action.disabled ? 0.5 : 1
}],
onPress: action.onPress,
disabled: action.disabled || action.loading,
activeOpacity: 0.7,
children: action.loading ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: styles.loadingContainer,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.loadingDot, {
backgroundColor: isTextAction ? '#FFFFFF' : colors.primary
}]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.loadingDot, {
backgroundColor: isTextAction ? '#FFFFFF' : colors.primary
}]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.loadingDot, {
backgroundColor: isTextAction ? '#FFFFFF' : colors.primary
}]
})]
}) : isTextAction ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.actionText, {
color: '#FFFFFF'
}],
children: action.text
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: action.icon,
size: 18,
color: colors.primary
})
}, action.key || idx);
};
const renderRightActions = () => {
if (rightActions?.length) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: styles.rightActionsRow,
children: rightActions.map((a, i) => renderRightActionButton(a, i))
});
}
if (rightAction) return renderRightActionButton(rightAction, 0);
return null;
};
const renderTitle = () => {
const titleStyle = variant === 'large' ? styles.titleLarge : variant === 'minimal' ? styles.titleMinimal : styles.titleDefault;
const subtitleStyle = variant === 'large' ? styles.subtitleLarge : variant === 'minimal' ? styles.subtitleMinimal : subtitleVariant === 'small' ? styles.subtitleSmall : subtitleVariant === 'large' ? styles.subtitleLarge : subtitleVariant === 'muted' ? styles.subtitleMuted : styles.subtitleDefault;
const getTitleAlignment = () => {
switch (titleAlignment) {
case 'center':
return styles.titleContainerCenter;
case 'right':
return styles.titleContainerRight;
default:
return styles.titleContainerLeft;
}
};
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.titleContainer, getTitleAlignment(), variant === 'minimal' && styles.titleContainerMinimal],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [titleStyle, {
color: colors.text.primary
}],
children: title
}), subtitle && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [subtitleStyle, {
color: colors.text.secondary
}],
children: subtitle
})]
});
};
const getElevationStyle = () => {
switch (elevation) {
case 'none':
return {};
case 'subtle':
return _reactNative.Platform.select({
web: {
boxShadow: isDarkTheme ? '0 1px 3px rgba(0,0,0,0.3)' : '0 1px 3px rgba(0,0,0,0.1)'
},
default: {
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 1
},
shadowOpacity: isDarkTheme ? 0.3 : 0.1,
shadowRadius: 3,
elevation: 2
}
});
case 'prominent':
return _reactNative.Platform.select({
web: {
boxShadow: isDarkTheme ? '0 4px 12px rgba(0,0,0,0.4)' : '0 4px 12px rgba(0,0,0,0.15)'
},
default: {
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 4
},
shadowOpacity: isDarkTheme ? 0.4 : 0.15,
shadowRadius: 12,
elevation: 8
}
});
default:
return {};
}
};
const getBackgroundStyle = () => {
if (variant === 'gradient') {
return {
backgroundColor: isDarkTheme ? '#1C1C1E' : '#FFFFFF',
// Add gradient overlay effect
borderBottomWidth: 1,
borderBottomColor: colors.border
};
}
return {
backgroundColor: colors.background,
borderBottomWidth: elevation === 'none' ? 0 : 1,
borderBottomColor: colors.border
};
};
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.container, getBackgroundStyle(), getElevationStyle()],
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [styles.content, variant === 'minimal' && styles.contentMinimal],
children: [renderBackButton(), renderTitle(), renderRightActions(), renderCloseButton()]
})
});
};
const styles = _reactNative.StyleSheet.create({
container: {
paddingTop: _reactNative.Platform.OS === 'ios' ? 50 : 16,
paddingBottom: 12,
top: 0,
left: 0,
right: 0,
zIndex: 1000,
..._reactNative.Platform.select({
web: {
position: 'sticky'
},
default: {
position: 'absolute'
}
})
},
content: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 16,
position: 'relative',
minHeight: 40
},
contentMinimal: {
paddingHorizontal: 12,
minHeight: 36
},
backButton: {
width: 32,
height: 32,
borderRadius: 16,
alignItems: 'center',
justifyContent: 'center',
marginRight: 10
},
closeButton: {
width: 32,
height: 32,
borderRadius: 16,
alignItems: 'center',
justifyContent: 'center',
marginLeft: 10
},
titleContainer: {
flex: 1,
alignItems: 'flex-start',
justifyContent: 'center'
},
titleContainerLeft: {
alignItems: 'flex-start'
},
titleContainerCenter: {
alignItems: 'center'
},
titleContainerRight: {
alignItems: 'flex-end'
},
titleContainerMinimal: {
alignItems: 'center',
marginHorizontal: 16
},
titleDefault: {
fontSize: 18,
fontWeight: '700',
fontFamily: _fonts.fontFamilies.phuduBold,
letterSpacing: -0.5,
lineHeight: 22
},
titleLarge: {
fontSize: 28,
fontWeight: '800',
fontFamily: _fonts.fontFamilies.phuduExtraBold,
letterSpacing: -1,
lineHeight: 34,
marginBottom: 3
},
titleMinimal: {
fontSize: 16,
fontWeight: '600',
fontFamily: _fonts.fontFamilies.phuduSemiBold,
letterSpacing: -0.3,
lineHeight: 20
},
subtitleDefault: {
fontSize: 14,
fontWeight: '400',
lineHeight: 17,
marginTop: 1
},
subtitleLarge: {
fontSize: 16,
fontWeight: '400',
lineHeight: 19,
marginTop: 3
},
subtitleMinimal: {
fontSize: 13,
fontWeight: '400',
lineHeight: 15,
marginTop: 1
},
subtitleSmall: {
fontSize: 12,
fontWeight: '400',
lineHeight: 14,
marginTop: 0
},
subtitleMuted: {
fontSize: 14,
fontWeight: '400',
lineHeight: 17,
marginTop: 1,
opacity: 0.7
},
rightActionButton: {
alignItems: 'center',
justifyContent: 'center',
marginLeft: 10
},
iconActionButton: {
width: 32,
height: 32,
borderRadius: 16
},
textActionButton: {
paddingHorizontal: 14,
paddingVertical: 6,
borderRadius: 18,
minWidth: 56
},
actionText: {
fontSize: 14,
fontWeight: '600',
fontFamily: _fonts.fontFamilies.phuduSemiBold,
letterSpacing: -0.2
},
loadingContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 2
},
loadingDot: {
width: 4,
height: 4,
borderRadius: 2,
opacity: 0.6
},
rightActionsRow: {
flexDirection: 'row',
alignItems: 'center'
}
});
var _default = exports.default = Header;
//# sourceMappingURL=Header.js.map