@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
JavaScript
"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.