davbyte-mobile-native 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HybridShell.d.ts +27 -0
- package/dist/HybridShell.d.ts.map +1 -0
- package/dist/HybridShell.js +63 -0
- package/dist/NativeTabBar.d.ts +9 -0
- package/dist/NativeTabBar.d.ts.map +1 -0
- package/dist/NativeTabBar.js +38 -0
- package/dist/WebViewHost.d.ts +8 -0
- package/dist/WebViewHost.d.ts.map +1 -0
- package/dist/WebViewHost.js +46 -0
- package/dist/__mocks__/react-native.d.ts +16 -0
- package/dist/__mocks__/react-native.d.ts.map +1 -0
- package/dist/__mocks__/react-native.js +7 -0
- package/dist/defineTab.d.ts +10 -0
- package/dist/defineTab.d.ts.map +1 -0
- package/dist/defineTab.js +4 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type NativeBridge } from "davbyte-mobile-bridge/native";
|
|
3
|
+
import { type TabConfig } from "./defineTab.js";
|
|
4
|
+
import type { WebViewHostRef } from "./types.js";
|
|
5
|
+
type HybridShellContextValue = {
|
|
6
|
+
tabs: TabConfig[];
|
|
7
|
+
activeTab: string;
|
|
8
|
+
setActiveTab: (id: string) => void;
|
|
9
|
+
webViewRef: React.RefObject<WebViewHostRef | null>;
|
|
10
|
+
bridge: NativeBridge;
|
|
11
|
+
onMessageFromWeb: (data: {
|
|
12
|
+
type: string;
|
|
13
|
+
payload?: unknown;
|
|
14
|
+
}) => void;
|
|
15
|
+
handleTabPress: (id: string) => void;
|
|
16
|
+
bottomNavHeight: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function useHybridShell(): HybridShellContextValue;
|
|
19
|
+
export type HybridShellProps<TId extends string = string> = {
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
tabs?: TabConfig<TId>[];
|
|
22
|
+
defaultTab?: TId;
|
|
23
|
+
onTabChange?: (id: TId) => void;
|
|
24
|
+
};
|
|
25
|
+
export declare function HybridShell<TId extends string = string>({ children, tabs, defaultTab, onTabChange, }: HybridShellProps<TId>): import("react").JSX.Element;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=HybridShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HybridShell.d.ts","sourceRoot":"","sources":["../src/HybridShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,KAAK,uBAAuB,GAAG;IAC7B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACnD,MAAM,EAAE,YAAY,CAAC;IACrB,gBAAgB,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACtE,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,wBAAgB,cAAc,IAAI,uBAAuB,CAMxD;AAED,MAAM,MAAM,gBAAgB,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IAC1D,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,wBAAgB,WAAW,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,EAAE,EACvD,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,WAAW,GACZ,EAAE,gBAAgB,CAAC,GAAG,CAAC,+BA0EvB"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
3
|
+
import { createNativeBridge, tabNavigationPlugin, } from "davbyte-mobile-bridge/native";
|
|
4
|
+
import { BOTTOM_NAV_HEIGHT } from "./defineTab.js";
|
|
5
|
+
const HybridShellContext = createContext(null);
|
|
6
|
+
export function useHybridShell() {
|
|
7
|
+
const ctx = useContext(HybridShellContext);
|
|
8
|
+
if (!ctx) {
|
|
9
|
+
throw new Error("useHybridShell must be used within HybridShell");
|
|
10
|
+
}
|
|
11
|
+
return ctx;
|
|
12
|
+
}
|
|
13
|
+
export function HybridShell({ children, tabs, defaultTab, onTabChange, }) {
|
|
14
|
+
const tabList = tabs ?? [];
|
|
15
|
+
const initialTab = defaultTab ?? tabList[0]?.id ?? "";
|
|
16
|
+
const [activeTab, setActiveTabState] = useState(initialTab);
|
|
17
|
+
const webViewRef = useRef(null);
|
|
18
|
+
const activeTabRef = useRef(activeTab);
|
|
19
|
+
activeTabRef.current = activeTab;
|
|
20
|
+
const postToWebView = useCallback((data) => {
|
|
21
|
+
webViewRef.current?.postMessageToWebView(data);
|
|
22
|
+
}, []);
|
|
23
|
+
const bridgeRef = useRef(null);
|
|
24
|
+
if (!bridgeRef.current) {
|
|
25
|
+
bridgeRef.current = createNativeBridge({ postToWebView });
|
|
26
|
+
}
|
|
27
|
+
const bridge = bridgeRef.current;
|
|
28
|
+
const validViews = useMemo(() => tabList.map((t) => t.id), [tabList]);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (tabList.length === 0)
|
|
31
|
+
return;
|
|
32
|
+
const cleanup = bridge.use(tabNavigationPlugin({
|
|
33
|
+
validViews,
|
|
34
|
+
getActiveTab: () => activeTabRef.current,
|
|
35
|
+
setActiveTab: (view) => {
|
|
36
|
+
setActiveTabState(view);
|
|
37
|
+
onTabChange?.(view);
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
return cleanup;
|
|
41
|
+
}, [bridge, tabList.length, validViews, onTabChange]);
|
|
42
|
+
const setActiveTab = useCallback((id) => {
|
|
43
|
+
setActiveTabState(id);
|
|
44
|
+
onTabChange?.(id);
|
|
45
|
+
}, [onTabChange]);
|
|
46
|
+
const handleTabPress = useCallback((id) => {
|
|
47
|
+
setActiveTab(id);
|
|
48
|
+
bridge.navigateTo(id);
|
|
49
|
+
}, [setActiveTab, bridge]);
|
|
50
|
+
const onMessageFromWeb = useMemo(() => bridge.createMessageHandler(), [bridge]);
|
|
51
|
+
const bottomNavHeight = tabList.length > 0 ? BOTTOM_NAV_HEIGHT : 0;
|
|
52
|
+
const value = {
|
|
53
|
+
tabs: tabList,
|
|
54
|
+
activeTab,
|
|
55
|
+
setActiveTab,
|
|
56
|
+
webViewRef,
|
|
57
|
+
bridge,
|
|
58
|
+
onMessageFromWeb,
|
|
59
|
+
handleTabPress,
|
|
60
|
+
bottomNavHeight,
|
|
61
|
+
};
|
|
62
|
+
return (_jsx(HybridShellContext.Provider, { value: value, children: children }));
|
|
63
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type NativeTabBarProps = {
|
|
2
|
+
activeColor?: string;
|
|
3
|
+
inactiveColor?: string;
|
|
4
|
+
backgroundColor?: string;
|
|
5
|
+
borderColor?: string;
|
|
6
|
+
bottomInset?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function NativeTabBar({ activeColor, inactiveColor, backgroundColor, borderColor, bottomInset, }: NativeTabBarProps): import("react").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=NativeTabBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeTabBar.d.ts","sourceRoot":"","sources":["../src/NativeTabBar.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,YAAY,CAAC,EAC3B,WAAuB,EACvB,aAAyB,EACzB,eAA2B,EAC3B,WAAuB,EACvB,WAAe,GAChB,EAAE,iBAAiB,sCAwDnB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Ionicons } from "@expo/vector-icons";
|
|
3
|
+
import { Pressable, Text, View } from "react-native";
|
|
4
|
+
import { useHybridShell } from "./HybridShell.js";
|
|
5
|
+
import { BOTTOM_NAV_HEIGHT } from "./defineTab.js";
|
|
6
|
+
export function NativeTabBar({ activeColor = "#00482A", inactiveColor = "#666666", backgroundColor = "#FFFFFF", borderColor = "#00482A", bottomInset = 0, }) {
|
|
7
|
+
const { tabs, activeTab, handleTabPress } = useHybridShell();
|
|
8
|
+
if (tabs.length === 0) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return (_jsx(View, { style: {
|
|
12
|
+
position: "absolute",
|
|
13
|
+
bottom: bottomInset,
|
|
14
|
+
left: 0,
|
|
15
|
+
right: 0,
|
|
16
|
+
height: BOTTOM_NAV_HEIGHT,
|
|
17
|
+
backgroundColor,
|
|
18
|
+
borderTopWidth: 2,
|
|
19
|
+
borderTopColor: borderColor,
|
|
20
|
+
flexDirection: "row",
|
|
21
|
+
zIndex: 1000,
|
|
22
|
+
}, children: tabs.map((tab) => {
|
|
23
|
+
const isActive = activeTab === tab.id;
|
|
24
|
+
const iconName = isActive
|
|
25
|
+
? String(tab.icon).replace("-outline", "")
|
|
26
|
+
: tab.icon;
|
|
27
|
+
return (_jsxs(Pressable, { style: {
|
|
28
|
+
flex: 1,
|
|
29
|
+
justifyContent: "center",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
paddingVertical: 8,
|
|
32
|
+
}, onPress: () => handleTabPress(tab.id), accessibilityRole: "tab", accessibilityState: { selected: isActive }, children: [_jsx(Ionicons, { name: iconName, size: 24, color: isActive ? activeColor : inactiveColor }), _jsx(Text, { style: {
|
|
33
|
+
fontSize: 12,
|
|
34
|
+
marginTop: 4,
|
|
35
|
+
color: isActive ? activeColor : inactiveColor,
|
|
36
|
+
}, children: tab.title })] }, tab.id));
|
|
37
|
+
}) }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WebViewHostRef } from "./types.js";
|
|
2
|
+
export type WebViewHostProps = {
|
|
3
|
+
html: string;
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
onLoadEnd?: () => void;
|
|
6
|
+
};
|
|
7
|
+
export declare const WebViewHost: import("react").ForwardRefExoticComponent<WebViewHostProps & import("react").RefAttributes<WebViewHostRef>>;
|
|
8
|
+
//# sourceMappingURL=WebViewHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebViewHost.d.ts","sourceRoot":"","sources":["../src/WebViewHost.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,WAAW,6GAkDvB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useImperativeHandle, useRef } from "react";
|
|
3
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
4
|
+
import { WebView } from "react-native-webview";
|
|
5
|
+
import { useHybridShell } from "./HybridShell.js";
|
|
6
|
+
export const WebViewHost = forwardRef(({ html, baseUrl = "https://localhost/", onLoadEnd }, _ref) => {
|
|
7
|
+
const { webViewRef, onMessageFromWeb } = useHybridShell();
|
|
8
|
+
const internalRef = useRef(null);
|
|
9
|
+
useImperativeHandle(webViewRef, () => ({
|
|
10
|
+
postMessageToWebView(data) {
|
|
11
|
+
internalRef.current?.postMessage(JSON.stringify(data));
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
const handleMessage = (event) => {
|
|
15
|
+
try {
|
|
16
|
+
const data = JSON.parse(event.nativeEvent.data);
|
|
17
|
+
onMessageFromWeb(data);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// Invalid message — ignore
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
if (!html) {
|
|
24
|
+
return (_jsx(View, { style: styles.errorContainer, children: _jsx(Text, { style: styles.errorText, children: "Web content not loaded. Run `npm run build` in the web folder first." }) }));
|
|
25
|
+
}
|
|
26
|
+
return (_jsx(WebView, { ref: internalRef, source: { html, baseUrl }, onMessage: handleMessage, onLoadEnd: onLoadEnd, style: styles.webview, javaScriptEnabled: true, domStorageEnabled: true, scrollEnabled: true, bounces: true, nestedScrollEnabled: true, showsVerticalScrollIndicator: true, showsHorizontalScrollIndicator: false, overScrollMode: "always", allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false }));
|
|
27
|
+
});
|
|
28
|
+
WebViewHost.displayName = "WebViewHost";
|
|
29
|
+
const styles = StyleSheet.create({
|
|
30
|
+
webview: {
|
|
31
|
+
flex: 1,
|
|
32
|
+
backgroundColor: "transparent",
|
|
33
|
+
},
|
|
34
|
+
errorContainer: {
|
|
35
|
+
flex: 1,
|
|
36
|
+
justifyContent: "center",
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
backgroundColor: "white",
|
|
39
|
+
},
|
|
40
|
+
errorText: {
|
|
41
|
+
color: "#a31515",
|
|
42
|
+
textAlign: "center",
|
|
43
|
+
margin: 20,
|
|
44
|
+
fontSize: 16,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const View = "View";
|
|
2
|
+
export declare const Text = "Text";
|
|
3
|
+
export declare const Pressable = "Pressable";
|
|
4
|
+
export declare const StyleSheet: {
|
|
5
|
+
create: <T extends Record<string, unknown>>(styles: T) => T;
|
|
6
|
+
};
|
|
7
|
+
declare const _default: {
|
|
8
|
+
View: string;
|
|
9
|
+
Text: string;
|
|
10
|
+
Pressable: string;
|
|
11
|
+
StyleSheet: {
|
|
12
|
+
create: <T extends Record<string, unknown>>(styles: T) => T;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export default _default;
|
|
16
|
+
//# sourceMappingURL=react-native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-native.d.ts","sourceRoot":"","sources":["../../src/__mocks__/react-native.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,SAAS,CAAC;AAC3B,eAAO,MAAM,IAAI,SAAS,CAAC;AAC3B,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,UAAU;aACZ,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,KAAG,CAAC;CAC1D,CAAC;;;;;;iBADS,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,KAAG,CAAC;;;AAG3D,wBAAqD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import type { Ionicons } from "@expo/vector-icons";
|
|
3
|
+
export type TabConfig<TId extends string = string> = {
|
|
4
|
+
id: TId;
|
|
5
|
+
title: string;
|
|
6
|
+
icon: ComponentProps<typeof Ionicons>["name"];
|
|
7
|
+
};
|
|
8
|
+
export declare function defineTab<TId extends string>(config: TabConfig<TId>): TabConfig<TId>;
|
|
9
|
+
export declare const BOTTOM_NAV_HEIGHT = 60;
|
|
10
|
+
//# sourceMappingURL=defineTab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineTab.d.ts","sourceRoot":"","sources":["../src/defineTab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,MAAM,SAAS,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IACnD,EAAE,EAAE,GAAG,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;CAC/C,CAAC;AAEF,wBAAgB,SAAS,CAAC,GAAG,SAAS,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAEpF;AAED,eAAO,MAAM,iBAAiB,KAAK,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { TabConfig } from "./defineTab.js";
|
|
2
|
+
export { defineTab, BOTTOM_NAV_HEIGHT } from "./defineTab.js";
|
|
3
|
+
export type { BridgeMessage, WebViewHostRef } from "./types.js";
|
|
4
|
+
export { HybridShell, useHybridShell } from "./HybridShell.js";
|
|
5
|
+
export type { HybridShellProps } from "./HybridShell.js";
|
|
6
|
+
export { WebViewHost } from "./WebViewHost.js";
|
|
7
|
+
export type { WebViewHostProps } from "./WebViewHost.js";
|
|
8
|
+
export { NativeTabBar } from "./NativeTabBar.js";
|
|
9
|
+
export type { NativeTabBarProps } from "./NativeTabBar.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,MAAM,cAAc,GAAG;IAC3B,oBAAoB,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "davbyte-mobile-native",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Native shell components for DavByte hybrid Expo + WebView apps",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@expo/vector-icons": ">=14.0.0",
|
|
22
|
+
"davbyte-mobile-bridge": ">=0.1.0",
|
|
23
|
+
"react": ">=18.0.0",
|
|
24
|
+
"react-native": ">=0.76.0",
|
|
25
|
+
"react-native-safe-area-context": ">=4.0.0",
|
|
26
|
+
"react-native-webview": ">=13.0.0"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@expo/vector-icons": "^15.0.3",
|
|
30
|
+
"@testing-library/react": "^16.3.0",
|
|
31
|
+
"@types/react": "^19.1.0",
|
|
32
|
+
"davbyte-mobile-bridge": "*",
|
|
33
|
+
"jsdom": "^27.0.0",
|
|
34
|
+
"react": "^19.1.0",
|
|
35
|
+
"react-native": "^0.81.0",
|
|
36
|
+
"react-native-webview": "^13.15.0",
|
|
37
|
+
"typescript": "^5.7.0",
|
|
38
|
+
"vitest": "^4.0.18"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/DavByte/create-app.git",
|
|
44
|
+
"directory": "packages/davbyte-mobile-native"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
49
|
+
}
|