UNPKG

@hoddy-ui/next

Version:

Core rich react native components written in typescript, with support for expo-router

1,508 lines (1,481 loc) 72.7 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var next_exports = {}; __export(next_exports, { AdaptiveStatusBar: () => AdaptiveStatusBarNext_default, AlertX: () => AlertX_default, Avatar: () => Avatar_default, Button: () => Button_default, CheckBox: () => CheckBox, Divider: () => Divider, FormWrapper: () => FormWrapper, Grid: () => Grid, GridItem: () => GridItem, IconButton: () => IconButton, LinkButton: () => LinkButton, Locator: () => Locator, OTPInput: () => OTPInput, Popup: () => Popup, RatingInput: () => RatingInput, RatingStars: () => RatingStars, SafeAreaView: () => SafeAreaView, SelectMenu: () => SelectMenu_default, Spinner: () => Spinner_default, TextField: () => TextField_default, TextField2: () => TextField2, Typography: () => Typography_default, UIThemeContext: () => UIThemeContext, UIThemeProvider: () => UIThemeProvider, default: () => next_default, getLocationFromPlaceId: () => getLocationFromPlaceId, getPredictionsFromCoords: () => getPredictionsFromCoords, getPredictionsFromQuery: () => getPredictionsFromQuery, showFlashMessage: () => showFlashMessage, useColors: () => useColors, useNavScreenOptions: () => useNavScreenOptions, useTheme: () => useTheme }); module.exports = __toCommonJS(next_exports); // ../src/theme/colors.ts var extraColors = {}; var setExtraColors = (c) => extraColors = c; function colors(theme) { const lightColors = { white: { 1: "#ffffff", 2: "#f7f7f7", 3: "#eeeeee", 4: "#dddddd", 5: "#bbbbbb", ...extraColors?.light?.white }, black: { 1: "#888888", 2: "#777777", 3: "#555555", 4: "#333333", 5: "#000000", ...extraColors?.light?.black } }; const darkColors = { black: { 1: "#ffffff", 2: "#f7f7f7", 3: "#eeeeee", 4: "#dddddd", 5: "#aaaaaa", ...extraColors?.dark?.black }, white: { 1: "#060606", 2: "#222222", 3: "#333333", 4: "#444444", 5: "#555555", ...extraColors?.dark?.white }, dark: { main: "#f2f3f4", light: "#ffffff", dark: "#dddddd", text: "#000000", ...extraColors?.dark?.dark }, light: { main: "#111111", light: "#555555", dark: "#333333", text: "#ffffff", ...extraColors?.dark?.light }, textSecondary: { main: "#666666", light: "#777777", dark: "#444444", text: "#ffffff", ...extraColors?.dark?.textSecondary }, primary: { main: "#ff8800", light: "#feffd3", dark: "#ffaa00", text: "#ffffff", ...extraColors?.light?.primary, ...extraColors?.dark?.primary } }; const dynamicColors = theme === "dark" ? darkColors : lightColors; return { ...extraColors[theme], primary: { main: "#ff8800", light: "#feffd3", dark: "#ffaa00", text: "#ffffff", ...extraColors?.light?.primary }, secondary: { main: "#ff1111", light: "#ff4433", dark: "#dd0000", text: "#ffffff", ...extraColors?.light?.secondary }, light: { main: "#ffffff", light: "#ffffff", dark: "#dddddd", text: "#000000", ...extraColors?.light?.light }, dark: { main: "#000000", light: "#777777", dark: "#111111", text: "#ffffff", ...extraColors?.light?.dark }, textSecondary: { main: "#aaaaaa", light: "#bbbbbb", dark: "#777777", text: "#112233", ...extraColors?.light?.textSecondary }, blue: { main: "#0099ff", light: "#3399ff", dark: "#002288", text: "#ffffff", ...extraColors?.light?.blue }, info: { main: "#0099ff", light: "#33aaff", dark: "#0088aa", text: "#ffffff", ...extraColors?.light?.info }, success: { main: "#00aa44", text: "#ffffff", light: "#55cc33", dark: "#006622", ...extraColors?.light?.success }, warning: { main: "#ffaa22", light: "#ffcc77", dark: "#ff9900", text: "#ffffff", ...extraColors?.light?.warning }, error: { main: "#dd2222", text: "#ffffff", light: "#ff4433", dark: "#aa2200", ...extraColors?.light?.error }, ...dynamicColors }; } // ../src/config/KeyManager.ts var config = { GOOGLE_MAP_API_KEY: "", EDGE_TO_EDGE: false }; function setConfig(key) { config = key; } function getConfig() { return config; } // ../src/config/index.ts function initialize(config2) { try { setConfig({ GOOGLE_MAP_API_KEY: config2.googleMapApiKey, DEFAULT_FONT_FAMILY: config2.fontFamily, EDGE_TO_EDGE: config2.edgeToEdge ?? false }); if (config2.colors) setExtraColors(config2.colors); } catch (error) { console.error("Error reading the config file:", error); } } // components/AdaptiveStatusBarNext.tsx var import_expo_router = require("expo-router"); var import_react5 = __toESM(require("react")); var import_react_native5 = require("react-native"); // ../src/hooks.ts var import_react4 = require("react"); var import_react_native4 = require("react-native"); var import_react_native_size_matters3 = require("react-native-size-matters"); // ../src/theme/index.tsx var import_async_storage = __toESM(require("@react-native-async-storage/async-storage")); var NavigationBar = __toESM(require("expo-navigation-bar")); var SystemUI = __toESM(require("expo-system-ui")); var import_react3 = __toESM(require("react")); var import_react_native3 = require("react-native"); var import_react_native_safe_area_context2 = require("react-native-safe-area-context"); // ../src/Components/FlashMessage.tsx var import_react2 = __toESM(require("react")); var import_react_native2 = require("react-native"); var import_react_native_safe_area_context = require("react-native-safe-area-context"); var import_react_native_size_matters2 = require("react-native-size-matters"); // ../src/Components/Typography.tsx var import_react = __toESM(require("react")); var import_react_native = require("react-native"); var import_react_native_size_matters = require("react-native-size-matters"); var Typography = (0, import_react.forwardRef)( ({ children, color = "dark", style = {}, textCase = null, variant = "body1", align = "left", gutterBottom = 0, adjustsFontSizeToFit, fontWeight = 400, fontFamily, // NEW PROP ADDED ...props }, ref) => { const colors2 = useColors(); const fontSize = { h1: (0, import_react_native_size_matters.moderateScale)(42), h2: (0, import_react_native_size_matters.moderateScale)(37), h3: (0, import_react_native_size_matters.moderateScale)(32), h4: (0, import_react_native_size_matters.moderateScale)(27), h5: (0, import_react_native_size_matters.moderateScale)(22), h6: (0, import_react_native_size_matters.moderateScale)(17), body1: (0, import_react_native_size_matters.moderateScale)(15), body2: (0, import_react_native_size_matters.moderateScale)(12), caption: (0, import_react_native_size_matters.moderateScale)(10) }; const styles2 = import_react_native.StyleSheet.create({ text: { fontSize: fontSize[variant], marginBottom: (0, import_react_native_size_matters.verticalScale)(gutterBottom) || 0, color: colors2[color]?.main || color, textTransform: textCase, alignItems: "center", textAlign: align, fontWeight, fontFamily: fontFamily || getConfig().DEFAULT_FONT_FAMILY || void 0 // Use custom font if provided, else default } }); return /* @__PURE__ */ import_react.default.createElement( import_react_native.Text, { ref, adjustsFontSizeToFit, style: [styles2.text, style], ...props }, children ); } ); var Typography_default = Typography; // ../src/Components/FlashMessage.tsx var showFlashMessage = () => { }; var FlashMessage = () => { const { top } = (0, import_react_native_safe_area_context.useSafeAreaInsets)(); const [message, setMessage] = (0, import_react2.useState)(null); const [show, setShow] = (0, import_react2.useState)(false); const colors2 = useColors(); const type = message?.type || "success"; showFlashMessage = (msg) => { setMessage(msg); setTimeout(() => { setShow(true); }, 50); setTimeout(() => { setShow(false); setTimeout(() => { setMessage(null); }, 500); }, msg.duration || 3e3); }; (0, import_react2.useEffect)(() => { import_react_native2.LayoutAnimation.configureNext(import_react_native2.LayoutAnimation.Presets.easeInEaseOut); }, [show]); const styles2 = import_react_native_size_matters2.ScaledSheet.create({ root: { position: "absolute", top: show ? 0 : -200, zIndex: 1e3, left: 0, paddingTop: top + 10, paddingHorizontal: "15@ms", backgroundColor: colors2[type].main, width: "100%", borderBottomLeftRadius: 10, borderBottomRightRadius: 10, paddingBottom: "15@ms" }, action: { borderRadius: 20, marginTop: "10@vs", flexDirection: "row", justifyContent: "center", paddingHorizontal: "20@ms", paddingVertical: "8@vs", backgroundColor: "#fff3" } }); return /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles2.root }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flexDirection: "row" } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flex: 1, marginRight: 10 } }, message?.title && /* @__PURE__ */ import_react2.default.createElement( Typography_default, { variant: "h6", fontWeight: 600, gutterBottom: 3, style: { color: "#fff" } }, message?.title ), /* @__PURE__ */ import_react2.default.createElement(Typography_default, { style: { color: "#fff" } }, message?.message))), message?.actions?.map((cur, i) => /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { key: i, style: styles2.action, onPress: cur.onPress }, /* @__PURE__ */ import_react2.default.createElement(Typography_default, { fontWeight: 700, style: { color: "#fff" } }, cur.title)))); }; var FlashMessage_default = FlashMessage; // ../src/theme/index.tsx var UIThemeContext = (0, import_react3.createContext)({ themeState: { mode: "default", value: "light" } }); function themeReducer(state, { type, payload }) { switch (type) { case "dark": return { mode: "dark", value: "dark" }; case "default": return { mode: "default", value: payload }; case "light": return { mode: "light", value: "light" }; default: return state; } } var ConfigureSystemUI = () => { const theme = useTheme(); const colors2 = useColors(); (0, import_react3.useEffect)(() => { const config2 = getConfig(); if (colors2) { SystemUI.setBackgroundColorAsync(colors2.white[1]); if (import_react_native3.Platform.OS === "android" && !config2.EDGE_TO_EDGE) { NavigationBar.setBackgroundColorAsync(colors2.white[1]); if (theme === "dark") { NavigationBar.setButtonStyleAsync("light"); } else { NavigationBar.setButtonStyleAsync("dark"); } } } }, [colors2, theme]); return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null); }; var UIThemeProvider = ({ children }) => { const [themeState, themeDispatch] = (0, import_react3.useReducer)(themeReducer, { mode: "default", value: "light" }); const colorScheme = (0, import_react_native3.useColorScheme)(); import_react3.default.useEffect(() => { import_async_storage.default.getItem("theme").then((val) => { if (val) { if (val === "default") { themeDispatch({ type: "default", payload: colorScheme }); } else themeDispatch({ type: val }); } else { themeDispatch({ type: "default", payload: colorScheme }); } }); }, [colorScheme]); return /* @__PURE__ */ import_react3.default.createElement(import_react_native_safe_area_context2.SafeAreaProvider, null, /* @__PURE__ */ import_react3.default.createElement( UIThemeContext.Provider, { value: { themeState, themeDispatch } }, children, /* @__PURE__ */ import_react3.default.createElement(FlashMessage_default, null), /* @__PURE__ */ import_react3.default.createElement(ConfigureSystemUI, null) )); }; // ../src/hooks.ts var useColors = () => { const { themeState } = (0, import_react4.useContext)(UIThemeContext); return colors(themeState.value); }; var useTheme = () => { const { themeState } = (0, import_react4.useContext)(UIThemeContext); return themeState.value; }; var useNavScreenOptions = (type) => { const colors2 = useColors(); const theme = useTheme(); const options = { stack: { headerShown: false, headerStyle: { backgroundColor: colors2.white[1] }, headerShadowVisible: false, contentStyle: { backgroundColor: colors2.white[1] }, headerTitleStyle: { color: colors2.black[1] }, headerTintColor: import_react_native4.Platform.OS === "android" ? colors2.black[1] : colors2.blue.light }, tab: { headerShown: false, headerTintColor: colors2.dark.main, tabBarStyle: { borderTopColor: theme === "dark" ? colors2.light.main : colors2.white[2], borderTopWidth: 1, // shadowColor: "#000", // shadowOffset: { height: -3, width: 0 }, // shadowRadius: 7, // shadowOpacity: 0.1, backgroundColor: colors2.white[1] }, tabBarActiveTintColor: colors2.blue.main, tabBarInactiveTintColor: colors2.textSecondary.main, tabBarLabelStyle: { // fontSize: ms(12), } }, drawer: { headerShown: false, drawerActiveTintColor: colors2.primary.main, drawerInactiveTintColor: colors2.textSecondary.main, sceneContainerStyle: { backgroundColor: colors2.white[2] }, drawerStyle: { backgroundColor: colors2.white[1] }, headerStyle: { backgroundColor: colors2.white[1] }, headerTitleStyle: { color: colors2.dark.main } } }; if (import_react_native4.Platform.OS === "android") { options.tab.tabBarStyle.height = import_react_native4.Dimensions.get("screen").height * 0.08; options.tab.tabBarStyle.paddingBottom = (0, import_react_native_size_matters3.vs)(15); } return options[type]; }; // components/AdaptiveStatusBarNext.tsx var AdaptiveStatusBar = ({ translucent = false }) => { const [focused, setFocused] = (0, import_react5.useState)(false); const colors2 = useColors(); const theme = useTheme(); const statusbarHandler = () => { import_react_native5.StatusBar.setBarStyle(theme === "dark" ? "light-content" : "dark-content"); if (import_react_native5.Platform.OS === "android") { import_react_native5.StatusBar.setBackgroundColor( translucent ? "transparent" : colors2.white[1] ); import_react_native5.StatusBar.setTranslucent(true); } }; (0, import_expo_router.useFocusEffect)( import_react5.default.useCallback(() => { statusbarHandler(); }, [theme]) ); import_react5.default.useEffect(() => { statusbarHandler(); }, [theme]); return /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null); }; var AdaptiveStatusBarNext_default = AdaptiveStatusBar; // ../src/Components/AlertX.tsx var import_vector_icons = require("@expo/vector-icons"); var import_react6 = __toESM(require("react")); var import_react_native6 = require("react-native"); var import_react_native_size_matters4 = require("react-native-size-matters"); var AlertX = ({ type = "info", variant = "contained", title, gutterBottom = 0, body, style = {} }) => { const colors2 = useColors(); const styles2 = import_react_native_size_matters4.ScaledSheet.create({ container: { padding: 20, paddingTop: 10, paddingBottom: 10, borderRadius: 8, alignItems: "center", flexDirection: "row", marginBottom: gutterBottom + "@ms", backgroundColor: colors2[type].main + (variant === "contained" ? "" : "3") }, title: { color: variant === "contained" ? "#fff" : colors2[type].main }, body: { color: variant === "contained" ? "#fff" : colors2[type].main } }); return /* @__PURE__ */ import_react6.default.createElement(import_react_native6.View, { style: { ...styles2.container, ...style } }, /* @__PURE__ */ import_react6.default.createElement(import_react_native6.View, { style: { width: "80%" } }, /* @__PURE__ */ import_react6.default.createElement(Typography_default, { style: styles2.title, gutterBottom: 3, fontWeight: 700 }, title), body && /* @__PURE__ */ import_react6.default.createElement(Typography_default, { fontWeight: 700, variant: "body2", style: styles2.body }, body)), /* @__PURE__ */ import_react6.default.createElement(import_react_native6.View, { style: { marginLeft: "auto" } }, /* @__PURE__ */ import_react6.default.createElement( import_vector_icons.MaterialIcons, { color: variant === "contained" ? "#fff" : colors2[type].main, size: 36, name: type === "success" ? "check" : type } ))); }; var AlertX_default = AlertX; // ../src/Components/Avatar.tsx var import_vector_icons2 = require("@expo/vector-icons"); var import_react7 = __toESM(require("react")); var import_react_native7 = require("react-native"); var import_react_native_size_matters5 = require("react-native-size-matters"); var Avatar = ({ color = "dark", label, variant = "contained", source, size = 48, style = {} }) => { const colors2 = useColors(); const styles2 = import_react_native_size_matters5.ScaledSheet.create({ root: { borderRadius: 150, height: size + "@ms", width: size + "@ms", alignItems: "center", justifyContent: "center", overflow: "hidden", borderWidth: variant === "outlined" ? 5 : 0, borderColor: variant === "outlined" ? "#fff" : "#0000", backgroundColor: variant === "outlined" ? null : label ? colors2[color].main : colors2.white[4], ...style }, image: { height: "110%", width: "110%" } }); return /* @__PURE__ */ import_react7.default.createElement(import_react_native7.View, { style: styles2.root }, source ? /* @__PURE__ */ import_react7.default.createElement(import_react_native7.Image, { resizeMode: "cover", style: styles2.image, source }) : label ? /* @__PURE__ */ import_react7.default.createElement(Typography_default, { style: { color: colors2[color].text } }, label[0]) : /* @__PURE__ */ import_react7.default.createElement(import_vector_icons2.AntDesign, { name: "user", color: "#fff", size: Math.round(size / 1.5) })); }; var Avatar_default = Avatar; // ../src/Components/Button.tsx var import_vector_icons3 = require("@expo/vector-icons"); var import_react8 = __toESM(require("react")); var import_react_native8 = require("react-native"); var import_react_native_size_matters6 = require("react-native-size-matters"); var LinkButton = ({ title, style = {}, color = "blue", fontSize = 12, fontWeight = "400", disabled, onPress = () => { } }) => { const colors2 = useColors(); const styles2 = import_react_native_size_matters6.ScaledSheet.create({ text: { fontSize: (0, import_react_native_size_matters6.moderateScale)(fontSize), fontWeight, fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System", color: disabled ? "#777" : colors2[color].main } }); return /* @__PURE__ */ import_react8.default.createElement(import_react_native8.TouchableOpacity, { onPress, disabled }, /* @__PURE__ */ import_react8.default.createElement(import_react_native8.Text, { style: { ...styles2.text, ...style } }, title)); }; var IconButton = ({ style = {}, color = "dark", disabled, icon, elevation, bg = false, size = 24, containerStyles = {}, onPress = () => { }, iconType = "material" }) => { const colors2 = useColors(); const theme = useTheme(); const bgColor = theme === "light" ? "#fff" : "#222"; const styles2 = import_react_native_size_matters6.ScaledSheet.create({ container: { alignSelf: "flex-start", flexGrow: 0, backgroundColor: bg ? bgColor : elevation > 0 ? bgColor : null, padding: "5@ms", shadowColor: "#000", shadowOpacity: 0.1, shadowOffset: { height: 1, width: 0 }, height: bg ? size + 20 + "@ms" : void 0, width: bg ? size + 20 + "@ms" : void 0, alignItems: "center", justifyContent: "center", shadowRadius: elevation, elevation, borderRadius: size * 5 }, text: { color: disabled ? "#777" : colors2[color].main } }); const IconComp = { material: import_vector_icons3.MaterialIcons, ion: import_vector_icons3.Ionicons }[iconType]; return /* @__PURE__ */ import_react8.default.createElement( import_react_native8.TouchableOpacity, { onPress, activeOpacity: 0.3, style: { ...styles2.container, ...containerStyles } }, /* @__PURE__ */ import_react8.default.createElement(IconComp, { style: { ...styles2.text, ...style }, name: icon, size }) ); }; var Button = (0, import_react8.forwardRef)( ({ elevation = 0, onPress = () => { }, disabled = false, title, loading, size = "normal", rounded = false, gutterBottom, style = {}, fullWidth = false, translucent = false, color = "primary", variant = "contained", start, end }, ref) => { const colors2 = useColors(); const styles2 = import_react_native_size_matters6.ScaledSheet.create({ con: { flexDirection: "row", alignItems: "center", alignSelf: "flex-start", justifyContent: "center", backgroundColor: variant === "text" || variant === "outlined" ? null : translucent ? translucent === "dark" ? colors2.white[3] + "22" : colors2.black[3] + "22" : loading ? colors2[color].light : disabled ? colors2.white[4] : colors2[color].main, borderRadius: rounded ? 30 : 10, elevation: variant === "text" ? 0 : elevation, paddingVertical: size === "small" ? 8 : size === "large" ? "15@ms" : "13@ms", paddingHorizontal: size === "small" ? "10@ms" : "18@ms", borderColor: colors2[color].main, borderWidth: variant === "outlined" ? 1 : 0, shadowColor: "#000", shadowRadius: elevation, marginBottom: gutterBottom, shadowOffset: { height: elevation / 2, width: 0 }, shadowOpacity: variant === "text" ? 0 : 0.3, width: fullWidth ? "100%" : null, ...style }, text: { color: disabled ? variant === "text" || variant === "outlined" ? colors2.black[1] : colors2[color].text : colors2[color][variant === "text" || variant === "outlined" ? "main" : "text"], fontWeight: variant === "outlined" ? "700" : "500", fontSize: size === "small" ? "12@ms" : "16@ms", fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System" } }); return /* @__PURE__ */ import_react8.default.createElement( import_react_native8.TouchableOpacity, { ref, onPress, disabled, style: styles2.con }, start, loading && /* @__PURE__ */ import_react8.default.createElement( import_react_native8.ActivityIndicator, { size: "small", color: colors2[color].text, style: { marginRight: 10 } } ), /* @__PURE__ */ import_react8.default.createElement(import_react_native8.Text, { style: styles2.text }, title), end ); } ); var Button_default = Button; // ../src/Components/Checkbox.tsx var import_vector_icons4 = require("@expo/vector-icons"); var import_react9 = __toESM(require("react")); var import_react_native9 = require("react-native"); var import_react_native_size_matters7 = require("react-native-size-matters"); var CheckBox = ({ color = "primary", checked, size = 24, label, style = {}, onChange }) => { const iconName = checked ? "checkbox-marked" : "checkbox-blank-outline"; const colors2 = useColors(); const styles2 = import_react_native_size_matters7.ScaledSheet.create({ container: { alignItems: "center", flexDirection: "row", ...style } }); return /* @__PURE__ */ import_react9.default.createElement(import_react_native9.View, { style: styles2.container }, /* @__PURE__ */ import_react9.default.createElement(import_react_native9.TouchableOpacity, { onPress: onChange }, /* @__PURE__ */ import_react9.default.createElement( import_vector_icons4.MaterialCommunityIcons, { name: iconName, size, color: colors2[color].main } )), label); }; // ../src/Components/FormWrapper.tsx var import_react10 = __toESM(require("react")); var import_react_native10 = require("react-native"); var import_react_native_size_matters8 = require("react-native-size-matters"); var FormWrapper = ({ children, behavior = import_react_native10.Platform.OS === "ios" ? "padding" : "height", contentContainerStyle, mode = "scroll", keyboardVerticalOffset = 10, style = {}, onScroll }) => { const styles2 = import_react_native_size_matters8.ScaledSheet.create({ root: { width: "100%", flex: 1, ...style } }); return mode === "static" ? /* @__PURE__ */ import_react10.default.createElement(import_react_native10.TouchableWithoutFeedback, { onPress: import_react_native10.Keyboard.dismiss, accessible: false }, /* @__PURE__ */ import_react10.default.createElement( import_react_native10.KeyboardAvoidingView, { style: styles2.root, behavior, contentContainerStyle: styles2.root, keyboardVerticalOffset }, children )) : /* @__PURE__ */ import_react10.default.createElement( import_react_native10.KeyboardAvoidingView, { behavior, style: styles2.root, keyboardVerticalOffset }, /* @__PURE__ */ import_react10.default.createElement( import_react_native10.ScrollView, { onScroll, showsVerticalScrollIndicator: false, scrollEventThrottle: 40, keyboardDismissMode: "interactive", contentContainerStyle, keyboardShouldPersistTaps: "handled" }, children ) ); }; // ../src/Components/StarRating.tsx var import_vector_icons5 = require("@expo/vector-icons"); var Haptics = __toESM(require("expo-haptics")); var import_react12 = require("react"); var import_react_native12 = require("react-native"); var import_react_native_size_matters10 = require("react-native-size-matters"); // ../src/Components/Popup.tsx var import_react_native11 = require("react-native"); var import_react11 = __toESM(require("react")); var import_react_native_size_matters9 = require("react-native-size-matters"); var Popup = ({ title, sheet, bare = false, keyboardVerticalOffset, children, open, onClose = () => { }, style }) => { const theme = useTheme(); const colors2 = useColors(); const [show, setShow] = (0, import_react11.useState)(open); const [showSecondary, setShowSecondary] = (0, import_react11.useState)(false); const styles2 = import_react_native_size_matters9.ScaledSheet.create({ root: { height: "100%", width: "100%", justifyContent: sheet ? "flex-end" : "center" }, avoidingView: { minHeight: typeof sheet === "number" ? sheet : void 0, maxHeight: "80%", zIndex: 1e3, alignSelf: "center", maxWidth: sheet ? void 0 : "90%", width: sheet ? "100%" : void 0 }, container: { paddingBottom: sheet ? "30@ms" : 0, backgroundColor: theme === "dark" ? "#111" : colors2.white[2], borderTopLeftRadius: 20, borderTopRightRadius: 20, borderBottomRightRadius: sheet ? 0 : 20, borderBottomLeftRadius: sheet ? 0 : 20, width: "100%", ...style }, content: { paddingHorizontal: bare ? void 0 : "15@ms" // flex: 1, }, title: { flexDirection: "row", alignItems: "center", justifyContent: "center", height: "50@ms" }, titleIcon: { position: "absolute", left: "15@ms" }, backdrop: { position: "absolute", height: "100%", zIndex: -1, width: "100%", backgroundColor: "#000b" } }); import_react11.default.useEffect(() => { if (open) { setShow(open); setTimeout(() => { setShowSecondary(open); }, 500); } else { closeAction(); } }, [open]); const closeAction = () => { setShowSecondary(false); setTimeout(() => { setShow(false); onClose(); }, 300); }; return /* @__PURE__ */ import_react11.default.createElement(import_react11.default.Fragment, null, /* @__PURE__ */ import_react11.default.createElement( import_react_native11.Modal, { transparent: true, animationType: "fade", statusBarTranslucent: true, visible: show, onRequestClose: closeAction }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles2.backdrop }), /* @__PURE__ */ import_react11.default.createElement(UIThemeProvider, null, /* @__PURE__ */ import_react11.default.createElement( import_react_native11.Modal, { transparent: true, animationType: "slide", statusBarTranslucent: true, visible: showSecondary, onRequestClose: closeAction }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.TouchableWithoutFeedback, { onPress: import_react_native11.Keyboard.dismiss }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles2.root }, open && /* @__PURE__ */ import_react11.default.createElement( import_react_native11.Pressable, { style: import_react_native11.StyleSheet.absoluteFill, onPress: closeAction } ), /* @__PURE__ */ import_react11.default.createElement( import_react_native11.KeyboardAvoidingView, { style: styles2.avoidingView, keyboardVerticalOffset, behavior: import_react_native11.Platform.OS === "ios" ? "position" : "padding" }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles2.container }, !bare && /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles2.title }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles2.titleIcon }, /* @__PURE__ */ import_react11.default.createElement( IconButton, { size: 20, icon: "close", onPress: closeAction } )), /* @__PURE__ */ import_react11.default.createElement(Typography_default, { align: "center", fontWeight: 500 }, title)), /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles2.content }, children)) ))) )) )); }; // ../src/Components/StarRating.tsx var RatingStars = ({ rating = 0, size = 16 }) => { const colors2 = useColors(); const styles2 = import_react_native_size_matters10.ScaledSheet.create({ root: { flexDirection: "row", alignItems: "center" } }); return /* @__PURE__ */ React.createElement(import_react_native12.View, { style: styles2.root }, [...Array(Math.floor(rating))].map((_, index) => /* @__PURE__ */ React.createElement(import_vector_icons5.Ionicons, { key: index, name: "star", size, color: "#FFD700" })), [...Array(5 - Math.floor(rating))].map((_, index) => /* @__PURE__ */ React.createElement( import_vector_icons5.Ionicons, { key: index, name: "star", size, color: colors2.textSecondary.light } ))); }; var RatingInput = ({ onSubmit: _onSubmit, rating = 0, size = 16 }) => { const [showReviewsModal, setShowReviewsModal] = (0, import_react12.useState)(false); const [rate, setRate] = (0, import_react12.useState)(0); const colors2 = useColors(); const [loading, setLoading] = (0, import_react12.useState)(false); const [review, setReview] = (0, import_react12.useState)(""); const styles2 = import_react_native_size_matters10.ScaledSheet.create({ root: { flexDirection: "row", alignItems: "center" }, inputCon: { marginBottom: "20@vs", backgroundColor: colors2.white[3], padding: "15@ms", borderRadius: 20 }, input: { fontSize: "16@ms", color: colors2.dark.main, height: "100@vs" } }); (0, import_react12.useEffect)(() => { setRate(rating); }, [rating]); const onRate = (index) => { setRate(index + 1); Haptics.selectionAsync(); setTimeout(() => { setShowReviewsModal(true); }, 500); }; const onSubmit = async () => { setLoading(true); setShowReviewsModal(false); _onSubmit && await _onSubmit({ rating: rate, review }); setLoading(false); }; return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(import_react_native12.View, { style: styles2.root }, loading ? /* @__PURE__ */ React.createElement(import_react_native12.ActivityIndicator, null) : [...Array(5)].map((_, index) => /* @__PURE__ */ React.createElement( import_react_native12.TouchableOpacity, { key: index, activeOpacity: 0.9, onPress: () => { onRate(index); } }, /* @__PURE__ */ React.createElement( import_vector_icons5.Ionicons, { style: { marginLeft: 10 }, name: index < rate ? "star" : "star-outline", size, color: colors2.primary.light } ) ))), /* @__PURE__ */ React.createElement( Popup, { sheet: true, open: showReviewsModal, onClose: () => { setShowReviewsModal(false); } }, /* @__PURE__ */ React.createElement( import_react_native12.View, { style: { alignItems: "center", marginBottom: 5 } }, /* @__PURE__ */ React.createElement(RatingStars, { rating: rate, size: 24 }) ), /* @__PURE__ */ React.createElement( Typography_default, { align: "center", fontWeight: 700, variant: "h5", gutterBottom: 20 }, "Add to your review" ), /* @__PURE__ */ React.createElement(import_react_native12.View, { style: styles2.inputCon }, /* @__PURE__ */ React.createElement( import_react_native12.TextInput, { style: styles2.input, multiline: true, value: review, onChangeText: (text) => setReview(text), placeholder: "Type review here.." } )), /* @__PURE__ */ React.createElement( Button_default, { gutterBottom: 40, title: "Submit Review", loading, disabled: loading, onPress: () => { onSubmit(); } } ) )); }; // ../src/Components/Grid.tsx var import_react_native13 = require("react-native"); var import_react13 = __toESM(require("react")); var import_react_native_size_matters11 = require("react-native-size-matters"); var GridItem = ({ children, col = 2, alignItems, spacing = 1, style = {} }) => { const styles2 = import_react_native_size_matters11.ScaledSheet.create({ gridItem: { width: 100 / col + "%", padding: spacing * 10 + "@ms", alignItems } }); return /* @__PURE__ */ import_react13.default.createElement(import_react_native13.View, { children, style: [styles2.gridItem, style] }); }; var Grid = ({ children, spacing = 1, style = {} }) => { const styles2 = import_react_native_size_matters11.ScaledSheet.create({ grid: { flexWrap: "wrap", margin: -spacing * 10 + "@ms", flexDirection: "row" } }); return /* @__PURE__ */ import_react13.default.createElement(import_react_native13.View, { children, style: [styles2.grid, style] }); }; // ../src/Components/Locator.tsx var import_vector_icons9 = require("@expo/vector-icons"); var import_react17 = __toESM(require("react")); var import_react_native17 = require("react-native"); // ../src/Components/List.tsx var import_vector_icons6 = require("@expo/vector-icons"); var import_react14 = __toESM(require("react")); var import_react_native14 = require("react-native"); var import_react_native_size_matters12 = require("react-native-size-matters"); var ListItem = ({ link = false, divider = false, onPress, index = 1, style = {}, children }) => { const colors2 = useColors(); const styles2 = import_react_native_size_matters12.ScaledSheet.create({ root: { flexDirection: "row", alignItems: "center", paddingHorizontal: "10@s", borderBottomColor: colors2.white[2], borderBottomWidth: divider ? 1 : 0, paddingVertical: "10@vs" } }); return /* @__PURE__ */ import_react14.default.createElement( import_react_native14.View, null, /* @__PURE__ */ import_react14.default.createElement(import_react_native14.TouchableOpacity, { disabled: Boolean(!onPress), onPress }, /* @__PURE__ */ import_react14.default.createElement(import_react_native14.View, { style: { ...styles2.root, ...style } }, children, link && /* @__PURE__ */ import_react14.default.createElement( import_vector_icons6.MaterialIcons, { color: colors2.white[5], style: { marginLeft: "auto" }, name: "arrow-forward-ios", size: 15 } ))) ); }; // ../src/Components/TextField.tsx var import_vector_icons8 = require("@expo/vector-icons"); var import_react16 = __toESM(require("react")); var import_react_native16 = require("react-native"); var import_react_native_size_matters14 = require("react-native-size-matters"); // ../src/Components/SelectMenu.tsx var import_vector_icons7 = require("@expo/vector-icons"); var import_react15 = __toESM(require("react")); var import_react_native15 = require("react-native"); var import_react_native_safe_area_context3 = require("react-native-safe-area-context"); var import_react_native_size_matters13 = require("react-native-size-matters"); var SelectMenu = ({ open = false, onClose, value, options = [], onChange, disableAutoClose = false, label, secondary, helperText }) => { const colors2 = useColors(); const { bottom } = (0, import_react_native_safe_area_context3.useSafeAreaInsets)(); const [search, setSearch] = (0, import_react15.useState)(""); const styles2 = import_react_native_size_matters13.ScaledSheet.create({ root: { backgroundColor: colors2.white[1], flex: 1 }, content: { flex: 1, paddingHorizontal: "10@ms" }, header: { paddingTop: "80@ms", marginBottom: "20@vs" }, option: { paddingHorizontal: "10@s", paddingVertical: "10@vs", borderRadius: 8, flexDirection: "row", alignItems: "center", marginBottom: "10@vs" }, footer: { paddingBottom: bottom, paddingHorizontal: "15@ms", paddingTop: "15@ms" } }); const renderItem = (0, import_react15.useCallback)( ({ item }) => /* @__PURE__ */ import_react15.default.createElement( import_react_native15.TouchableOpacity, { style: { ...styles2.option, backgroundColor: item.value === value ? colors2.blue.light + "22" : colors2.white[2] }, onPress: () => { onChange(item.value); if (!disableAutoClose) onClose(); }, key: item.label }, item.start && /* @__PURE__ */ import_react15.default.createElement(import_react_native15.View, { style: { marginRight: 10 } }, item.start), /* @__PURE__ */ import_react15.default.createElement(import_react_native15.View, { style: { flex: 1 } }, /* @__PURE__ */ import_react15.default.createElement( Typography_default, { style: { color: item.value === value ? colors2.blue.light : colors2.black[2] } }, item.label ), item.secondary ? /* @__PURE__ */ import_react15.default.createElement( Typography_default, { variant: "body2", style: { marginTop: 2, color: item.value === value ? colors2.blue.light : colors2.white[5] } }, item.secondary ) : null), value === item.value && /* @__PURE__ */ import_react15.default.createElement( import_vector_icons7.MaterialIcons, { name: "check", color: colors2.blue.light, size: 24, style: { marginLeft: "auto" } } ) ), [value, colors2] ); return /* @__PURE__ */ import_react15.default.createElement(import_react_native15.Modal, { visible: open, animationType: "slide", onRequestClose: onClose }, /* @__PURE__ */ import_react15.default.createElement(import_react_native15.View, { style: styles2.root }, /* @__PURE__ */ import_react15.default.createElement(import_react_native15.View, { style: styles2.content }, /* @__PURE__ */ import_react15.default.createElement(import_react_native15.View, { style: styles2.header }, /* @__PURE__ */ import_react15.default.createElement(Typography_default, { variant: "h5", gutterBottom: 5, fontWeight: 700 }, label), helperText ? /* @__PURE__ */ import_react15.default.createElement(Typography_default, { variant: "body2", color: "textSecondary" }, helperText) : null, /* @__PURE__ */ import_react15.default.createElement( TextField_default, { label: "Search", value: search, type: "search", onChangeText: setSearch, variant: "outlined" } )), /* @__PURE__ */ import_react15.default.createElement( import_react_native15.FlatList, { removeClippedSubviews: true, keyExtractor: (item) => item.value, renderItem, data: options.filter( (item) => search.length > 1 ? item.label.toLowerCase().indexOf(search.toLowerCase()) > -1 : item ).sort((a, b) => a.label.localeCompare(b.label)) } )), /* @__PURE__ */ import_react15.default.createElement(import_react_native15.View, { style: styles2.footer }, /* @__PURE__ */ import_react15.default.createElement( Button_default, { color: "error", variant: "outlined", fullWidth: true, title: "Close", onPress: onClose } )))); }; var SelectMenu_default = SelectMenu; // ../src/Components/TextField.tsx var TextField = ({ label, keyboardType, variant, color = "primary", value, type, helperText, onChangeText, onSubmitEditing = () => { }, onFocus = () => { }, onBlur = () => { }, error, start, size = "normal", rounded, disabled = false, style = {}, inputStyles = {}, gutterBottom = 0, end, options, ...props }) => { const colors2 = useColors(); const [focused, setFocused] = (0, import_react16.useState)(false); const height = (0, import_react_native_size_matters14.moderateScale)(variant === "text" ? 50 : 45) * (size === "large" ? 1.2 : size === "small" ? 0.8 : 1); const labelAnim = (0, import_react16.useRef)( new import_react_native16.Animated.Value(height / (0, import_react_native_size_matters14.moderateScale)(variant === "text" ? 2.5 : 3.2)) ).current; import_react16.default.useEffect(() => { if (focused || value) { import_react_native16.Animated.timing(labelAnim, { toValue: (0, import_react_native_size_matters14.verticalScale)(variant === "text" ? 2 : 4), duration: 300, useNativeDriver: false }).start(); } else { import_react_native16.Animated.timing(labelAnim, { toValue: height / (0, import_react_native_size_matters14.moderateScale)(variant === "text" ? 2.5 : 3.2), duration: 300, useNativeDriver: false }).start(); } }, [focused, value]); const styles2 = import_react_native_size_matters14.ScaledSheet.create({ root: { marginBottom: gutterBottom + "@vs", width: "100%", ...style }, container: { height, overflow: "hidden", backgroundColor: variant === "outlined" || variant === "text" ? "#fff0" : focused ? colors2.white[3] : colors2.white[4], flexDirection: "row", borderColor: error ? colors2.error.main : focused ? colors2[color].main : colors2.textSecondary.main, borderWidth: error ? 1 : variant === "outlined" ? focused ? 2 : 0.5 : 0, borderBottomWidth: variant === "text" ? 0.5 : void 0, width: "100%", borderRadius: variant === "text" ? 0 : rounded ? 30 : 7, alignItems: "center", ...inputStyles }, input: { fontSize: "14@s", flex: 1, alignSelf: "stretch", paddingLeft: variant === "text" ? 0 : (0, import_react_native_size_matters14.moderateScale)(15), paddingRight: (0, import_react_native_size_matters14.moderateScale)(10), paddingTop: "11@vs", fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System", color: colors2.black[1], zIndex: 10 // backgroundColor: "#284", }, inputText: { fontSize: "14@ms", flex: 1, paddingLeft: variant === "text" ? 0 : (0, import_react_native_size_matters14.moderateScale)(15), paddingTop: "13@ms" }, label: { fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System", position: "absolute", left: variant === "text" ? 0 : (0, import_react_native_size_matters14.moderateScale)(15), fontSize: focused || value ? "10@s" : "13@s", color: focused ? colors2[color].main : colors2.textSecondary.main }, helperText: { paddingHorizontal: "15@s", flex: 1, color: focused ? colors2[color].dark : colors2.textSecondary.main, paddingTop: "4@ms" }, error: { paddingLeft: 10, paddingRight: 10, paddingTop: 5, flexDirection: "row", alignItems: "center" }, errorText: { fontSize: 12, marginLeft: 10 } }); const formProps = type === "email" ? { textContentType: "emailAddress", keyboardType: "email-address", autoCapitalize: "none", autoCompleteType: "email" } : type === "number" ? { keyboardType: "numeric" } : type === "tel" ? { textContentType: "telephoneNumber", keyboardType: "phone-pad" } : type === "search" ? { keyboardType: "web-search", returnKeyType: "search", autoCapitalize: "none" } : type === "password" ? { secureTextEntry: true, autoCompleteType: "password", autoCapitalize: "none", textContentType: "password" } : {}; return /* @__PURE__ */ import_react16.default.createElement(import_react16.default.Fragment, null, /* @__PURE__ */ import_react16.default.createElement(import_react_native16.View, { style: styles2.root }, /* @__PURE__ */ import_react16.default.createElement( import_react_native16.TouchableOpacity, { onPress: () => setFocused(true), style: styles2.container }, /* @__PURE__ */ import_react16.default.createElement(import_react_native16.Animated.Text, { style: { ...styles2.label, top: labelAnim } }, label), start, options ? /* @__PURE__ */ import_react16.default.createElement( import_react_native16.View, { style: { flex: 1, alignItems: "center", flexDirection: "row" } }, options.find((cur) => cur.value === value)?.start && /* @__PURE__ */ import_react16.default.createElement( import_react_native16.View, { style: { paddingTop: variant !== "outlined" ? (0, import_react_native_size_matters14.ms)(13) : 0, paddingRight: 10 } }, options.find((cur) => cur.value === value)?.start ), /* @__PURE__ */ import_react16.default.