UNPKG

@hoddy-ui/next

Version:

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

1,473 lines (1,444 loc) 100 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, Animator: () => Animator, 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, TextFieldBase: () => TextFieldBase, Typography: () => Typography_default, UIThemeContext: () => UIThemeContext, UIThemeProvider: () => UIThemeProvider, default: () => next_default, getLocationFromPlaceId: () => getLocationFromPlaceId, getPredictionsFromCoords: () => getPredictionsFromCoords, getPredictionsFromQuery: () => getPredictionsFromQuery, showFlashMessage: () => showFlashMessage, useAppState: () => useAppState_default, useBlinkAnimation: () => useBlinkAnimation, useColors: () => useColors, useFadeAnimation: () => useFadeAnimation, useFloatAnimation: () => useFloatAnimation, useGrowAnimation: () => useGrowAnimation, useNavScreenOptions: () => useNavScreenOptions, useRollAnimation: () => useRollAnimation, useSlideAnimation: () => useSlideAnimation, useTheme: () => useTheme, useThemeContext: () => useThemeContext, useThrownUpAnimation: () => useThrownUpAnimation }); module.exports = __toCommonJS(next_exports); // ../src/theme/colors.ts var extraColors = {}; var setExtraColors = (c) => extraColors = c; var defaultPalettes = { primary: { main: "#ff8800", light: "#feffd3", dark: "#ffaa00", text: "#ffffff" }, secondary: { main: "#ff1111", light: "#ff4433", dark: "#dd0000", text: "#ffffff" }, light: { main: "#ffffff", light: "#ffffff", dark: "#dddddd", text: "#000000" }, dark: { main: "#000000", light: "#777777", dark: "#111111", text: "#ffffff" }, textSecondary: { main: "#aaaaaa", light: "#bbbbbb", dark: "#777777", text: "#ffffff" }, blue: { main: "#0099ff", light: "#3399ff", dark: "#002288", text: "#ffffff" }, info: { main: "#0099ff", light: "#33aaff", dark: "#0088aa", text: "#ffffff" }, success: { main: "#00aa44", light: "#55cc33", dark: "#006622", text: "#ffffff" }, warning: { main: "#ffaa22", light: "#ffcc77", dark: "#ff9900", text: "#ffffff" }, error: { main: "#dd2222", light: "#ff4433", dark: "#aa2200", text: "#ffffff" } }; var lightNeutrals = { white: { 1: "#ffffff", 2: "#f7f7f7", 3: "#eeeeee", 4: "#dddddd", 5: "#bbbbbb" }, black: { 1: "#888888", 2: "#777777", 3: "#555555", 4: "#333333", 5: "#000000" } }; var darkNeutrals = { white: { 1: "#060606", 2: "#222222", 3: "#333333", 4: "#444444", 5: "#555555" }, black: { 1: "#ffffff", 2: "#f7f7f7", 3: "#eeeeee", 4: "#dddddd", 5: "#aaaaaa" } }; var darkPaletteOverrides = { dark: { main: "#f2f3f4", light: "#ffffff", dark: "#dddddd", text: "#000000" }, light: { main: "#111111", light: "#555555", dark: "#333333", text: "#ffffff" }, textSecondary: { main: "#666666", light: "#777777", dark: "#444444", text: "#ffffff" } }; function colors(theme) { const isDark = theme === "dark"; const neutrals = isDark ? darkNeutrals : lightNeutrals; const overrides = isDark ? darkPaletteOverrides : {}; const baseDefaults = { ...neutrals, ...defaultPalettes }; const keys = /* @__PURE__ */ new Set([ ...Object.keys(baseDefaults), ...Object.keys(extraColors.light ?? {}), ...Object.keys(extraColors.dark ?? {}) ]); const themeInvertingKeys = /* @__PURE__ */ new Set([ "white", "black", "textSecondary", "dark", "light" ]); const result = {}; keys.forEach((key) => { const skipLightExtras = isDark && themeInvertingKeys.has(key); result[key] = { ...baseDefaults[key], ...overrides[key], ...skipLightExtras ? {} : extraColors.light?.[key], ...isDark ? extraColors.dark?.[key] : {} }; }); return result; } // ../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, TYPOGRAPHY: config2.typography, 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"); // ../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_reanimated = __toESM(require("react-native-reanimated")); 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"); // ../src/utility.ts var getFontFamily = (fontWeight) => { return getConfig().TYPOGRAPHY?.fontWeights?.[fontWeight] || getConfig().TYPOGRAPHY?.fontFamily || void 0; }; // ../src/Components/Typography.tsx var DEFAULT_FONT_SIZES = { h1: (0, import_react_native_size_matters.ms)(42), h2: (0, import_react_native_size_matters.ms)(37), h3: (0, import_react_native_size_matters.ms)(32), h4: (0, import_react_native_size_matters.ms)(27), h5: (0, import_react_native_size_matters.ms)(22), h6: (0, import_react_native_size_matters.ms)(17), body1: (0, import_react_native_size_matters.ms)(15), body2: (0, import_react_native_size_matters.ms)(12), caption: (0, import_react_native_size_matters.ms)(10) }; var Typography = (0, import_react.forwardRef)( ({ children, color = "dark", style = {}, textCase, variant = "body1", align = "left", gutterBottom = 0, adjustsFontSizeToFit, fontWeight = 400, fontFamily, // NEW PROP ADDED fontSize, lineHeight, ...props }, ref) => { const colors2 = useColors(); const config2 = getConfig(); const customFontSizes = config2.TYPOGRAPHY?.fontSizes; const baseFontSize = customFontSizes?.[variant] ?? DEFAULT_FONT_SIZES[variant]; const f = fontSize || style?.fontSize || baseFontSize; const lh = lineHeight || f * 1.2; const styles = import_react_native.StyleSheet.create({ text: { lineHeight: lh, fontSize: f, marginBottom: (0, import_react_native_size_matters.ms)(gutterBottom) || 0, color: colors2[color]?.main || color, textTransform: textCase, alignItems: "center", textAlign: align, fontWeight, fontFamily: fontFamily || getFontFamily(fontWeight) } }); return /* @__PURE__ */ import_react.default.createElement( import_react_native.Text, { ref, adjustsFontSizeToFit, style: [styles.text, style], ...props }, children ); } ); var Typography_default = Typography; // ../src/Components/FlashMessage.tsx var flashListeners = /* @__PURE__ */ new Set(); var showFlashMessage = (msg) => { flashListeners.forEach((listener) => listener(msg)); }; var subscribeToFlashMessages = (listener) => { flashListeners.add(listener); return () => { flashListeners.delete(listener); }; }; var FlashMessage = () => { const { top } = (0, import_react_native_safe_area_context.useSafeAreaInsets)(); const [message, setMessage] = (0, import_react2.useState)(null); const colors2 = useColors(); const type = message?.type || "success"; const timeoutRef = (0, import_react2.useRef)(null); const translateY = (0, import_react_native_reanimated.useSharedValue)(-200); const opacity = (0, import_react_native_reanimated.useSharedValue)(0); const hideMessage = () => { setMessage(null); }; const closeMessage = () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } translateY.value = (0, import_react_native_reanimated.withTiming)(-200, { duration: 300 }); opacity.value = (0, import_react_native_reanimated.withTiming)(0, { duration: 300 }, () => { (0, import_react_native_reanimated.runOnJS)(hideMessage)(); }); }; (0, import_react2.useEffect)(() => { const listener = (msg) => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } translateY.value = -200; opacity.value = 0; setMessage(msg); translateY.value = (0, import_react_native_reanimated.withTiming)(0, { duration: 300 }); opacity.value = (0, import_react_native_reanimated.withTiming)(1, { duration: 300 }); const duration = msg.duration || 3e3; timeoutRef.current = setTimeout(() => { translateY.value = (0, import_react_native_reanimated.withTiming)(-200, { duration: 300 }); opacity.value = (0, import_react_native_reanimated.withTiming)(0, { duration: 300 }, () => { (0, import_react_native_reanimated.runOnJS)(hideMessage)(); }); timeoutRef.current = null; }, duration); }; const unsubscribe = subscribeToFlashMessages(listener); return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } unsubscribe(); }; }, []); const animatedStyle = (0, import_react_native_reanimated.useAnimatedStyle)(() => { return { transform: [{ translateY: translateY.value }], opacity: opacity.value }; }); const textColor = type === "default" ? "#fff" : colors2[type].text; const styles = import_react_native_size_matters2.ScaledSheet.create({ root: { position: "absolute", top: 0, zIndex: 1e3, left: 0, paddingTop: top + 10, paddingHorizontal: "15@ms", backgroundColor: type === "default" ? "#333" : 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" } }); if (!message) return null; return /* @__PURE__ */ import_react2.default.createElement(import_react_native_reanimated.default.View, { style: [styles.root, animatedStyle] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: closeMessage, activeOpacity: 0.9 }, /* @__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, color: textColor }, message?.title ), /* @__PURE__ */ import_react2.default.createElement(Typography_default, { color: textColor }, message?.message)))), message?.actions?.map((cur, i) => /* @__PURE__ */ import_react2.default.createElement( import_react_native2.TouchableOpacity, { key: i, style: styles.action, onPress: () => { cur.onPress?.(); closeMessage(); } }, /* @__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 }) { import_async_storage.default.setItem("theme", type); 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") { if (config2.EDGE_TO_EDGE) { if (theme === "dark") { NavigationBar.setStyle("light"); } else { NavigationBar.setStyle("dark"); } } else { 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 }); import_react_native3.Appearance.setColorScheme(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 useThemeContext = () => { const { themeState: theme, themeDispatch } = (0, import_react4.useContext)(UIThemeContext); const colorScheme = (0, import_react_native4.useColorScheme)(); const setTheme = (theme2) => { if (theme2 === "default") { themeDispatch?.({ type: "default", payload: colorScheme }); } else { themeDispatch?.({ type: theme2 }); } }; return { theme, setTheme }; }; var useNavScreenOptions = (type) => { const colors2 = useColors(); 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: colors2.white[2], borderColor: colors2.white[2], borderTopWidth: 1, backgroundColor: colors2.white[1] }, tabBarActiveTintColor: colors2.primary.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 } } }; return options[type]; }; // components/AdaptiveStatusBarNext.tsx var AdaptiveStatusBar = ({ translucent = 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.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_matters3 = require("react-native-size-matters"); var AlertX = ({ type = "info", variant = "contained", title, gutterBottom = 0, body, style = {} }) => { const colors2 = useColors(); const styles = import_react_native_size_matters3.ScaledSheet.create({ container: { padding: 20, paddingTop: 10, paddingBottom: 10, borderRadius: 8, alignItems: "center", flexDirection: "row", marginBottom: (0, import_react_native_size_matters3.ms)(gutterBottom), 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: [styles.container, style] }, /* @__PURE__ */ import_react6.default.createElement(import_react_native6.View, { style: { width: "80%" } }, /* @__PURE__ */ import_react6.default.createElement(Typography_default, { style: styles.title, gutterBottom: 3, fontWeight: 700 }, title), body && /* @__PURE__ */ import_react6.default.createElement(Typography_default, { fontWeight: 700, variant: "body2", style: styles.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_matters4 = require("react-native-size-matters"); var Avatar = ({ color = "dark", label, variant = "contained", source, size = 48, style = {}, icon }) => { const colors2 = useColors(); const [imageError, setImageError] = (0, import_react7.useState)(false); const styles = import_react_native_size_matters4.ScaledSheet.create({ root: { borderRadius: 150, height: (0, import_react_native_size_matters4.ms)(size), width: (0, import_react_native_size_matters4.ms)(size), alignItems: "center", justifyContent: "center", overflow: "hidden", borderWidth: variant === "outlined" ? 5 : 0, borderColor: variant === "outlined" ? "#fff" : "#0000", backgroundColor: variant === "outlined" ? void 0 : label ? colors2[color].main : colors2.white[4], ...style }, image: { height: "110%", width: "110%" } }); return /* @__PURE__ */ import_react7.default.createElement(import_react_native7.View, { style: styles.root }, source && !imageError ? /* @__PURE__ */ import_react7.default.createElement( import_react_native7.Image, { resizeMode: "cover", style: styles.image, source, onError: () => setImageError(true) } ) : label ? /* @__PURE__ */ import_react7.default.createElement(Typography_default, { style: { color: colors2[color].text } }, label[0]) : icon ? icon : /* @__PURE__ */ import_react7.default.createElement(import_vector_icons2.Ionicons, { name: "person", 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_matters5 = require("react-native-size-matters"); var LinkButton = ({ title, style = {}, color = "blue", fontSize = 12, fontWeight = 400, disabled, onPress = () => { } }) => { const colors2 = useColors(); const styles = import_react_native_size_matters5.ScaledSheet.create({ text: { fontSize: (0, import_react_native_size_matters5.moderateScale)(fontSize), fontWeight: fontWeight.toString(), fontFamily: getFontFamily(fontWeight), 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: { ...styles.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 styles = import_react_native_size_matters5.ScaledSheet.create({ container: { alignSelf: "flex-start", flexGrow: 0, backgroundColor: bg ? bgColor : elevation > 0 ? bgColor : void 0, padding: "5@ms", shadowColor: "#000", shadowOpacity: 0.1, shadowOffset: { height: 1, width: 0 }, height: bg ? (0, import_react_native_size_matters5.ms)(size + 20) : void 0, width: bg ? (0, import_react_native_size_matters5.ms)(size + 20) : 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: { ...styles.container, ...containerStyles } }, /* @__PURE__ */ import_react8.default.createElement(IconComp, { style: { ...styles.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 styles = import_react_native_size_matters5.ScaledSheet.create({ con: { flexDirection: "row", alignItems: "center", alignSelf: "flex-start", justifyContent: "center", backgroundColor: variant === "text" || variant === "outlined" ? void 0 : variant === "translucent" ? colors2[color].main + "22" : 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@mvs" : "13@mvs", 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%" : void 0, ...style }, text: { color: disabled ? variant === "text" || variant === "outlined" || variant === "translucent" ? colors2.black[1] : colors2[color].text : colors2[color][variant === "text" || variant === "outlined" || variant === "translucent" ? "main" : "text"], fontWeight: variant === "outlined" ? "700" : variant === "translucent" ? "600" : "500", fontSize: size === "small" ? "12@ms" : "13@ms", fontFamily: getFontFamily( variant === "outlined" ? 700 : variant === "translucent" ? 600 : 500 ) } }); return /* @__PURE__ */ import_react8.default.createElement( import_react_native8.TouchableOpacity, { ref, onPress, disabled, style: styles.con }, start, loading && /* @__PURE__ */ import_react8.default.createElement( import_react_native8.ActivityIndicator, { size: "small", color: variant === "text" || variant === "outlined" || variant === "translucent" ? colors2[color].main : colors2[color].text, style: { marginRight: 10 } } ), /* @__PURE__ */ import_react8.default.createElement(import_react_native8.Text, { style: styles.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_matters6 = 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 styles = import_react_native_size_matters6.ScaledSheet.create({ container: { alignItems: "center", flexDirection: "row", ...style } }); return /* @__PURE__ */ import_react9.default.createElement(import_react_native9.View, { style: styles.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_safe_area_context3 = require("react-native-safe-area-context"); var import_react_native_size_matters7 = require("react-native-size-matters"); var FormWrapper = (0, import_react10.forwardRef)( ({ children, behavior = import_react_native10.Platform.OS === "ios" ? "padding" : "height", contentContainerStyle, mode = "scroll", keyboardVerticalOffset = 10, style = {}, onScroll }, ref) => { const { bottom } = (0, import_react_native_safe_area_context3.useSafeAreaInsets)(); const defaultOffset = import_react_native10.Platform.OS === "ios" ? -bottom : -bottom * 2; const styles = import_react_native_size_matters7.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: styles.root, behavior, contentContainerStyle: styles.root, keyboardVerticalOffset: keyboardVerticalOffset || defaultOffset }, children )) : /* @__PURE__ */ import_react10.default.createElement( import_react_native10.KeyboardAvoidingView, { behavior, style: styles.root, keyboardVerticalOffset: keyboardVerticalOffset || defaultOffset }, /* @__PURE__ */ import_react10.default.createElement( import_react_native10.ScrollView, { ref, 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 = __toESM(require("react")); var import_react_native12 = require("react-native"); var import_react_native_size_matters9 = 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_reanimated2 = __toESM(require("react-native-reanimated")); var import_react_native_safe_area_context4 = require("react-native-safe-area-context"); var import_react_native_size_matters8 = require("react-native-size-matters"); var Popup = ({ title, sheet = true, bare = false, keyboardVerticalOffset, children, open, onClose = () => { }, style, onModalShow, onModalHide, disableAutoKeyboardManagement = false }) => { const theme = useTheme(); const colors2 = useColors(); const [modalVisible, setModalVisible] = (0, import_react11.useState)(false); const [modalOpen, setModalOpen] = (0, import_react11.useState)(false); const [keyboardVisible, setKeyboardVisible] = (0, import_react11.useState)(false); const { bottom } = (0, import_react_native_safe_area_context4.useSafeAreaInsets)(); const backdropOpacity = (0, import_react_native_reanimated2.useSharedValue)(0); const contentTranslateY = (0, import_react_native_reanimated2.useSharedValue)(1e3); const keyboardVerticalOffsetValue = import_react_native11.Platform.OS === "ios" ? -bottom : -bottom * 2; (0, import_react11.useEffect)(() => { const keyboardDidShowListener = import_react_native11.Keyboard.addListener( "keyboardDidShow", () => { setKeyboardVisible(true); } ); const keyboardDidHideListener = import_react_native11.Keyboard.addListener( "keyboardDidHide", () => { setKeyboardVisible(false); } ); return () => { keyboardDidHideListener?.remove(); keyboardDidShowListener?.remove(); }; }, []); const _onModalShow = () => { setModalVisible(true); onModalShow?.(); }; const _onModalHide = () => { onModalHide?.(); setModalOpen(false); }; (0, import_react11.useEffect)(() => { if (open) { setModalOpen(true); backdropOpacity.value = (0, import_react_native_reanimated2.withTiming)(1, { duration: 300 }); contentTranslateY.value = (0, import_react_native_reanimated2.withTiming)(0, { duration: 300 }, () => { (0, import_react_native_reanimated2.runOnJS)(_onModalShow)(); }); } else { setModalVisible(false); backdropOpacity.value = (0, import_react_native_reanimated2.withTiming)(0, { duration: 200 }); contentTranslateY.value = (0, import_react_native_reanimated2.withTiming)(1e3, { duration: 200 }, () => { (0, import_react_native_reanimated2.runOnJS)(_onModalHide)(); }); } }, [open]); const backdropAnimatedStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => ({ opacity: backdropOpacity.value })); const contentAnimatedStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => ({ transform: [{ translateY: contentTranslateY.value }] })); const styles = import_react_native_size_matters8.ScaledSheet.create({ root: { height: "100%", width: "100%", justifyContent: sheet ? "flex-end" : "center" }, keyboardView: { flex: 1, zIndex: 1e3 }, avoidingView: { zIndex: 2, minHeight: typeof sheet === "number" ? sheet : void 0, maxHeight: "90%", alignSelf: "center", maxWidth: sheet ? void 0 : "90%", width: sheet ? "100%" : void 0, marginBottom: import_react_native11.Platform.OS === "android" && keyboardVisible ? bottom : 0 }, container: { paddingBottom: sheet && !bare ? bottom + (0, import_react_native_size_matters8.ms)(0) : void 0, backgroundColor: theme === "dark" ? "#111" : colors2.white[1], borderTopLeftRadius: 20, borderTopRightRadius: 20, borderBottomRightRadius: sheet ? 0 : 20, borderBottomLeftRadius: sheet ? 0 : 20, width: "100%", overflow: "hidden", ...style }, content: { maxHeight: sheet && !bare ? import_react_native11.Dimensions.get("screen").height * 0.9 - bottom - (0, import_react_native_size_matters8.ms)(60) : void 0, paddingHorizontal: bare ? void 0 : "15@ms" // backgroundColor : "#f94", }, 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" } }); const closeAction = () => { onClose(); }; return /* @__PURE__ */ import_react11.default.createElement( import_react_native11.Modal, { transparent: true, animationType: "none", statusBarTranslucent: true, visible: modalOpen, onRequestClose: closeAction, navigationBarTranslucent: true }, /* @__PURE__ */ import_react11.default.createElement(UIThemeProvider, null, /* @__PURE__ */ import_react11.default.createElement(import_react_native_reanimated2.default.View, { style: [styles.backdrop, backdropAnimatedStyle] }), /* @__PURE__ */ import_react11.default.createElement( import_react_native11.KeyboardAvoidingView, { style: styles.keyboardView, behavior: import_react_native11.Platform.OS === "ios" ? "padding" : "height", keyboardVerticalOffset: keyboardVerticalOffset || keyboardVerticalOffsetValue }, /* @__PURE__ */ import_react11.default.createElement( import_react_native11.TouchableWithoutFeedback, { onPress: import_react_native11.Keyboard.dismiss, disabled: disableAutoKeyboardManagement }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles.root }, modalOpen && /* @__PURE__ */ import_react11.default.createElement( import_react_native11.Pressable, { style: [import_react_native11.StyleSheet.absoluteFill, { zIndex: 1 }], onPress: closeAction } ), /* @__PURE__ */ import_react11.default.createElement( import_react_native_reanimated2.default.View, { style: [styles.avoidingView, contentAnimatedStyle], layout: modalVisible ? import_react_native_reanimated2.LinearTransition.springify().stiffness(200).mass(0.5).damping(100) : void 0 }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles.container }, !bare && /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles.title }, /* @__PURE__ */ import_react11.default.createElement(import_react_native11.View, { style: styles.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: styles.content }, children)) )) ) )) ); }; // ../src/Components/StarRating.tsx var RatingInput = ({ onSubmit: _onSubmit, rating = 0, size = 16, color = "primary" }) => { 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 styles = import_react_native_size_matters9.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__ */ import_react12.default.createElement(import_react12.default.Fragment, null, /* @__PURE__ */ import_react12.default.createElement(import_react_native12.View, { style: styles.root }, loading ? /* @__PURE__ */ import_react12.default.createElement(import_react_native12.ActivityIndicator, null) : [...Array(5)].map((_, index) => /* @__PURE__ */ import_react12.default.createElement( import_react_native12.TouchableOpacity, { key: index, activeOpacity: 0.9, onPress: () => { onRate(index); } }, /* @__PURE__ */ import_react12.default.createElement( import_vector_icons5.Ionicons, { style: { marginLeft: 10 }, name: index < rate ? "star" : "star-outline", size, color: colors2[color]?.main || color } ) ))), /* @__PURE__ */ import_react12.default.createElement( Popup, { sheet: true, open: showReviewsModal, onClose: () => { setShowReviewsModal(false); } }, /* @__PURE__ */ import_react12.default.createElement( import_react_native12.View, { style: { alignItems: "center", marginBottom: 5 } }, /* @__PURE__ */ import_react12.default.createElement(RatingStars, { rating: rate, size: 24 }) ), /* @__PURE__ */ import_react12.default.createElement( Typography_default, { align: "center", fontWeight: 700, variant: "h5", gutterBottom: 20 }, "Add to your review" ), /* @__PURE__ */ import_react12.default.createElement(import_react_native12.View, { style: styles.inputCon }, /* @__PURE__ */ import_react12.default.createElement( import_react_native12.TextInput, { style: styles.input, multiline: true, value: review, onChangeText: (text) => setReview(text), placeholder: "Type review here..", verticalAlign: "top" } )), /* @__PURE__ */ import_react12.default.createElement( Button_default, { gutterBottom: 40, title: "Submit Review", loading, disabled: loading, onPress: () => { onSubmit(); } } ) )); }; var RatingStars = ({ rating = 0, size = 16, color = "#FFD700", inactiveColor = "textSecondary" }) => { const colors2 = useColors(); const styles = import_react_native_size_matters9.ScaledSheet.create({ root: { flexDirection: "row", alignItems: "center" } }); return /* @__PURE__ */ import_react12.default.createElement(import_react_native12.View, { style: styles.root }, [...Array(Math.floor(rating))].map((_, index) => /* @__PURE__ */ import_react12.default.createElement( import_vector_icons5.Ionicons, { key: index, name: "star", size, color: colors2[color]?.main || color } )), [...Array(5 - Math.floor(rating))].map((_, index) => /* @__PURE__ */ import_react12.default.createElement( import_vector_icons5.Ionicons, { key: index, name: "star", size, color: colors2[inactiveColor]?.main || inactiveColor } ))); }; // ../src/Components/Grid.tsx var import_react13 = __toESM(require("react")); var import_react_native13 = require("react-native"); var import_react_native_size_matters10 = require("react-native-size-matters"); var GridItem = ({ children, col = 2, alignItems, spacing = 1, style = {} }) => { const styles = import_react_native_size_matters10.ScaledSheet.create({ gridItem: { width: `${100 / col}%`, padding: (0, import_react_native_size_matters10.ms)(spacing * 10), alignItems } }); return /* @__PURE__ */ import_react13.default.createElement(import_react_native13.View, { children, style: [styles.gridItem, style] }); }; var Grid = ({ children, spacing = 1, style = {} }) => { const styles = import_react_native_size_matters10.ScaledSheet.create({ grid: { flexWrap: "wrap", margin: `${-spacing * 10}@ms`, flexDirection: "row" } }); return /* @__PURE__ */ import_react13.default.createElement(import_react_native13.View, { children, style: [styles.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_matters11 = require("react-native-size-matters"); var ListItem = ({ link = false, divider = false, onPress, index = 1, style = {}, children }) => { const colors2 = useColors(); const styles = import_react_native_size_matters11.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: { ...styles.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_modal_datetime_picker = __toESM(require("react-native-modal-datetime-picker")); var import_react_native_size_matters13 = 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_context5 = require("react-native-safe-area-context"); var import_react_native_size_matters12 = require("react-native-size-matters"); var SelectMenu = ({ open = false, onClose, value, options = [], onChange, disableAutoClose = false, label, secondary, helperText, searchEnabled = false, searchPlaceholder = "Search" }) => { const colors2 = useColors(); const { bottom } = (0, import_react_native_safe_area_context5.useSafeAreaInsets)(); const [search, setSearch] = (0, import_react15.useState)(""); const styles = import_react_native_size_matters12.ScaledSheet.create({ header: { marginBottom: "20@vs" }, option: { paddingHorizontal: "10@s", paddingVertical: "10@vs", borderRadius: 8, flexDirection: "row", alignItems: "center", marginBottom: "10@vs" } }); const renderItem = (0, import_react15.useCallback)( ({ item }) => /* @__PURE__ */ import_react15.default.createElement( import_react_native15.TouchableOpacity, { style: { ...styles.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, { variant: "body2", 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( Popup, { open,