@mbrain/epic-react-native-lib 0.0.4 → 0.0.6
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/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/navigation/log-route.d.ts +12 -0
- package/dist/types/navigation/screen-content/ScreenContent.d.ts +137 -0
- package/dist/types/navigation/screen-content/utils.d.ts +5 -0
- package/dist/types/utils/android-navbar.d.ts +23 -0
- package/package.json +10 -2
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var Y=Object.create;var C=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var re=(e,t)=>{for(var r in t)C(e,r,{get:t[r],enumerable:!0})},v=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of ee(t))!oe.call(e,n)&&n!==r&&C(e,n,{get:()=>t[n],enumerable:!(o=Z(t,n))||o.enumerable});return e};var l=(e,t,r)=>(r=e!=null?Y(te(e)):{},v(t||!e||!e.__esModule?C(r,"default",{value:e,enumerable:!0}):r,e)),ne=e=>v(C({},"__esModule",{value:!0}),e);var ce={};re(ce,{Box1:()=>N,ScreenContent:()=>z,createLocalStorage:()=>E,useAndroidNavigationBar:()=>B,useLogRouteChange:()=>I,useOrientation:()=>O});module.exports=ne(ce);var g=l(require("react"),1),p=require("react-native");function N({style:e,children:t}){let[r,o]=(0,g.useState)(0);return g.default.createElement(p.View,{style:e},g.default.createElement(p.Text,{style:ae.text,onPress:()=>{o(n=>n+1)}},"Box1 ",r),t)}var ae=p.StyleSheet.create({text:{fontSize:20,padding:15,borderRadius:10,color:"#ffffff",backgroundColor:"#0a234a"}});var w=require("react"),y=l(require("expo-screen-orientation"),1);function O(){let[e,t]=(0,w.useState)({orientation:void 0,orientationLock:void 0});return(0,w.useEffect)(()=>{Promise.all([y.getOrientationAsync(),y.getOrientationLockAsync()]).then(([o,n])=>{t({orientation:o,orientationLock:n})});let r=y.addOrientationChangeListener(o=>{t({orientation:o.orientationInfo.orientation,orientationLock:o.orientationLock})});return()=>r.remove()},[]),e}var A=l(require("react"),1),x=require("react-native"),u=l(require("expo-navigation-bar"),1);function B(e){let t=(0,x.useColorScheme)();A.default.useEffect(()=>{if(x.Platform.OS!=="android")return;u.setStyle(t==="dark"?"dark":"light");let r=t==="dark"?e==null?void 0:e.dark:e==null?void 0:e.light;if(!r)return;(async()=>{let n=[];r.backgroundColor&&(u.setBackgroundColorAsync(r.backgroundColor),n.push(u.setBackgroundColorAsync(r.backgroundColor))),r.borderColor&&n.push(u.setBorderColorAsync(r.borderColor)),n.length&&await Promise.all(n)})()},[t,e==null?void 0:e.dark,e==null?void 0:e.light])}var T=require("react"),b=require("react-native-mmkv");function E({defaults:e,storage:t=(0,b.createMMKV)()}){let r=a=>{try{let i=t.getString(String(a));return i!==void 0?JSON.parse(i):e[a]}catch(i){return console.warn(i),e[a]}};return{useLocalStorage:a=>{let[i,d]=(0,T.useState)(()=>r(a));return(0,b.useMMKVListener)(h=>{String(a)===h&&d(r(a))},t),i},setLocalStorage:(a,i)=>{try{let d=JSON.stringify(i);t.set(String(a),d)}catch(d){console.warn(d)}},getLocalStorage:a=>r(a),removeLocalStorage:a=>{try{t.remove(String(a))}catch(i){console.warn(i)}},clearAllLocalStorage:()=>{try{t.clearAll()}catch(a){console.warn(a)}},storage:t}}var M=l(require("react"),1),F=require("expo-router"),H=l(require("lodash/isEmpty"),1);function I(){let e=(0,F.useNavigationContainerRef)();M.default.useEffect(()=>{if(__DEV__)return e.addListener("state",()=>{let r=e.getState(),o=D(r);o&&((0,H.default)(o.params)?console.log(`ROUTE CHANGED : ${o.name}`):console.log(`ROUTE CHANGED : ${o.name}`,o.params))})},[e])}function D(e){var t;if(!e)return null;if(e.routes&&e.routes.length>0){let r=(t=e.index)!=null?t:0,o=e.routes[r];if(!o)return null;if(o.state){let n=D(o.state);if(n)return n}return{name:o.name,params:o.params}}return null}var S=l(require("react"),1),m=require("react-native"),U=require("nativewind"),$=require("react-native-safe-area-context"),j=require("react-native-keyboard-controller");var f=l(require("react"),1),V=require("react-native"),K=require("@react-navigation/elements");function k(e){return(0,f.useMemo)(()=>e?typeof e=="function"?f.default.createElement(e,null):e:null,[e])}function _(e,t){let r=(0,K.useHeaderHeight)();return(0,f.useMemo)(()=>{let o=V.StyleSheet.flatten(e),n=o==null?void 0:o.padding,s=o==null?void 0:o.paddingTop,c=typeof s=="number"?s:typeof n=="number"?n:0;return t&&(c+=r),[J.flex,e,{paddingTop:c}]},[r,t,e])}function G(e,t){let r=(0,K.useHeaderHeight)();return(0,f.useMemo)(()=>{let o=V.StyleSheet.flatten(e),n=o==null?void 0:o.padding,s=o==null?void 0:o.paddingTop,c=typeof s=="number"?s:typeof n=="number"?n:0;return t&&(c+=r),[J.scrollContentStyle,e,{paddingTop:c}]},[e,r,t])}var J=V.StyleSheet.create({flex:{flex:1},scrollContentStyle:{flexGrow:1}});var ie=S.default.memo(function({scroll:t=!1,edges:r=[],headerTransparent:o=!1,scrollViewProps:n,scrollRef:s,style:c={},contentContainerStyle:P={},HeaderComponent:a,FooterComponent:i,BackgroundComponent:d,children:h}){let q=_(c,o),Q=G(P,o),W=k(a),X=k(i),L=k(d);return S.default.createElement(m.View,{style:R.flex},L&&S.default.createElement(m.View,{style:R.background},L),S.default.createElement($.SafeAreaView,{edges:r,style:R.flex},W,t&&S.default.createElement(j.KeyboardAwareScrollView,{ref:s,enabled:!0,scrollEnabled:!0,style:[R.flex,c],contentContainerStyle:Q,bottomOffset:40,disableScrollOnKeyboardHide:!0,keyboardShouldPersistTaps:"handled",showsVerticalScrollIndicator:!1,...n},h),!t&&S.default.createElement(m.View,{style:[{overflow:"hidden"},q]},h),X))}),R=m.StyleSheet.create({flex:{flex:1},background:{alignItems:"stretch",pointerEvents:"none",...m.StyleSheet.absoluteFill}}),z=(0,U.cssInterop)(ie,{className:"style",contentContainerClassName:"contentContainerStyle"});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import x,{useState as A}from"react";import{View as B,Text as T,StyleSheet as E}from"react-native";function M({style:e,children:o}){let[r,t]=A(0);return x.createElement(B,{style:e},x.createElement(T,{style:F.text,onPress:()=>{t(n=>n+1)}},"Box1 ",r),o)}var F=E.create({text:{fontSize:20,padding:15,borderRadius:10,color:"#ffffff",backgroundColor:"#0a234a"}});import{useEffect as H,useState as I}from"react";import*as u from"expo-screen-orientation";function D(){let[e,o]=I({orientation:void 0,orientationLock:void 0});return H(()=>{Promise.all([u.getOrientationAsync(),u.getOrientationLockAsync()]).then(([t,n])=>{o({orientation:t,orientationLock:n})});let r=u.addOrientationChangeListener(t=>{o({orientation:t.orientationInfo.orientation,orientationLock:t.orientationLock})});return()=>r.remove()},[]),e}import _ from"react";import{Platform as G,useColorScheme as J}from"react-native";import*as d from"expo-navigation-bar";function U(e){let o=J();_.useEffect(()=>{if(G.OS!=="android")return;d.setStyle(o==="dark"?"dark":"light");let r=o==="dark"?e==null?void 0:e.dark:e==null?void 0:e.light;if(!r)return;(async()=>{let n=[];r.backgroundColor&&(d.setBackgroundColorAsync(r.backgroundColor),n.push(d.setBackgroundColorAsync(r.backgroundColor))),r.borderColor&&n.push(d.setBorderColorAsync(r.borderColor)),n.length&&await Promise.all(n)})()},[o,e==null?void 0:e.dark,e==null?void 0:e.light])}import{useState as $}from"react";import{createMMKV as j,useMMKVListener as z}from"react-native-mmkv";function q({defaults:e,storage:o=j()}){let r=a=>{try{let i=o.getString(String(a));return i!==void 0?JSON.parse(i):e[a]}catch(i){return console.warn(i),e[a]}};return{useLocalStorage:a=>{let[i,l]=$(()=>r(a));return z(m=>{String(a)===m&&l(r(a))},o),i},setLocalStorage:(a,i)=>{try{let l=JSON.stringify(i);o.set(String(a),l)}catch(l){console.warn(l)}},getLocalStorage:a=>r(a),removeLocalStorage:a=>{try{o.remove(String(a))}catch(i){console.warn(i)}},clearAllLocalStorage:()=>{try{o.clearAll()}catch(a){console.warn(a)}},storage:o}}import Q from"react";import{useNavigationContainerRef as W}from"expo-router";import X from"lodash/isEmpty";function Y(){let e=W();Q.useEffect(()=>{if(__DEV__)return e.addListener("state",()=>{let r=e.getState(),t=b(r);t&&(X(t.params)?console.log(`ROUTE CHANGED : ${t.name}`):console.log(`ROUTE CHANGED : ${t.name}`,t.params))})},[e])}function b(e){var o;if(!e)return null;if(e.routes&&e.routes.length>0){let r=(o=e.index)!=null?o:0,t=e.routes[r];if(!t)return null;if(t.state){let n=b(t.state);if(n)return n}return{name:t.name,params:t.params}}return null}import S from"react";import{StyleSheet as P,View as h}from"react-native";import{cssInterop as ee}from"nativewind";import{SafeAreaView as te}from"react-native-safe-area-context";import{KeyboardAwareScrollView as oe}from"react-native-keyboard-controller";import Z,{useMemo as f}from"react";import{StyleSheet as g}from"react-native";import{useHeaderHeight as V}from"@react-navigation/elements";function p(e){return f(()=>e?typeof e=="function"?Z.createElement(e,null):e:null,[e])}function k(e,o){let r=V();return f(()=>{let t=g.flatten(e),n=t==null?void 0:t.padding,s=t==null?void 0:t.paddingTop,c=typeof s=="number"?s:typeof n=="number"?n:0;return o&&(c+=r),[K.flex,e,{paddingTop:c}]},[r,o,e])}function R(e,o){let r=V();return f(()=>{let t=g.flatten(e),n=t==null?void 0:t.padding,s=t==null?void 0:t.paddingTop,c=typeof s=="number"?s:typeof n=="number"?n:0;return o&&(c+=r),[K.scrollContentStyle,e,{paddingTop:c}]},[e,r,o])}var K=g.create({flex:{flex:1},scrollContentStyle:{flexGrow:1}});var re=S.memo(function({scroll:o=!1,edges:r=[],headerTransparent:t=!1,scrollViewProps:n,scrollRef:s,style:c={},contentContainerStyle:C={},HeaderComponent:a,FooterComponent:i,BackgroundComponent:l,children:m}){let L=k(c,t),v=R(C,t),N=p(a),O=p(i),w=p(l);return S.createElement(h,{style:y.flex},w&&S.createElement(h,{style:y.background},w),S.createElement(te,{edges:r,style:y.flex},N,o&&S.createElement(oe,{ref:s,enabled:!0,scrollEnabled:!0,style:[y.flex,c],contentContainerStyle:v,bottomOffset:40,disableScrollOnKeyboardHide:!0,keyboardShouldPersistTaps:"handled",showsVerticalScrollIndicator:!1,...n},m),!o&&S.createElement(h,{style:[{overflow:"hidden"},L]},m),O))}),y=P.create({flex:{flex:1},background:{alignItems:"stretch",pointerEvents:"none",...P.absoluteFill}}),ne=ee(re,{className:"style",contentContainerClassName:"contentContainerStyle"});export{M as Box1,ne as ScreenContent,q as createLocalStorage,U as useAndroidNavigationBar,Y as useLogRouteChange,D as useOrientation};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export { Box1 } from './components/Box1';
|
|
2
2
|
export { useOrientation } from './utils/orientation';
|
|
3
|
+
export { useAndroidNavigationBar } from './utils/android-navbar';
|
|
3
4
|
export { createLocalStorage } from './storage/local-storage';
|
|
5
|
+
export { useLogRouteChange } from './navigation/log-route';
|
|
6
|
+
export { ScreenContent, type ScreenContentProps, } from './navigation/screen-content/ScreenContent';
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { Edges } from 'react-native-safe-area-context';
|
|
4
|
+
import { KeyboardAwareScrollViewProps, KeyboardAwareScrollViewRef } from 'react-native-keyboard-controller';
|
|
5
|
+
type BaseScreenContentProps = {
|
|
6
|
+
/**
|
|
7
|
+
* Enable keyboard aware scrolling with [KeyboardAwareScrollView](https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-aware-scroll-view).
|
|
8
|
+
*
|
|
9
|
+
* ## Requirement
|
|
10
|
+
*
|
|
11
|
+
* Add [KeyboardProvider](https://kirillzyusko.github.io/react-native-keyboard-controller/docs/installation#adding-provider) as root app component.
|
|
12
|
+
*
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
scroll?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Safe area edges.
|
|
18
|
+
*/
|
|
19
|
+
edges?: Edges;
|
|
20
|
+
/**
|
|
21
|
+
* Set to true when screen option headerTransparent is true.
|
|
22
|
+
*
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
headerTransparent?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* A ref that will be attached to the underlying KeyboardAwareScrollView.
|
|
28
|
+
*
|
|
29
|
+
* Only used when scroll = true.
|
|
30
|
+
*
|
|
31
|
+
* ## Usage
|
|
32
|
+
*
|
|
33
|
+
* ```
|
|
34
|
+
* const scrollRef = useRef<KeyboardAwareScrollViewRef>(null);
|
|
35
|
+
* <ScreenContent scrollRef={scrollRef}>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
scrollRef?: React.Ref<KeyboardAwareScrollViewRef>;
|
|
39
|
+
/**
|
|
40
|
+
* Set [KeyboardAwareScrollView](https://kirillzyusko.github.io/react-native-keyboard-controller/docs/api/components/keyboard-aware-scroll-view) props. Only used when scroll = true.
|
|
41
|
+
*
|
|
42
|
+
* ## Usage
|
|
43
|
+
*
|
|
44
|
+
* ```
|
|
45
|
+
* scrollViewProps={{
|
|
46
|
+
* // The distance between the keyboard and the caret inside a focused TextInput when the keyboard is shown
|
|
47
|
+
* bottomOffset: 40,
|
|
48
|
+
* }}
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
scrollViewProps?: KeyboardAwareScrollViewProps;
|
|
52
|
+
/**
|
|
53
|
+
* Style applied to the container View.
|
|
54
|
+
*/
|
|
55
|
+
style?: StyleProp<ViewStyle>;
|
|
56
|
+
/**
|
|
57
|
+
* Style applied to KeyboardAwareScrollView contentContainerStyle. Only used when scroll = true.
|
|
58
|
+
*/
|
|
59
|
+
contentContainerStyle?: StyleProp<ViewStyle>;
|
|
60
|
+
/**
|
|
61
|
+
* Optional header component.
|
|
62
|
+
*/
|
|
63
|
+
HeaderComponent?: React.FC | React.ReactNode;
|
|
64
|
+
/**
|
|
65
|
+
* Optional footer component.
|
|
66
|
+
*
|
|
67
|
+
* ## Usage
|
|
68
|
+
*
|
|
69
|
+
* Keyboard toolbar is always visible.
|
|
70
|
+
*
|
|
71
|
+
* ```typescript
|
|
72
|
+
* function FooterComponent({ onSubmit }: { onSubmit?: (text: string) => void }) {
|
|
73
|
+
* const [message, setMessage] = useState('');
|
|
74
|
+
*
|
|
75
|
+
* return (
|
|
76
|
+
* <KeyboardStickyView className="bg-background px-5 pb-5 pt-3">
|
|
77
|
+
* <Input
|
|
78
|
+
* placeholder="Type a message"
|
|
79
|
+
* returnKeyType="send"
|
|
80
|
+
* value={message}
|
|
81
|
+
* autoCorrect={false}
|
|
82
|
+
* autoCapitalize="none"
|
|
83
|
+
* onChangeText={(text) => {
|
|
84
|
+
* setMessage(text);
|
|
85
|
+
* }}
|
|
86
|
+
* onSubmitEditing={({ nativeEvent: { text } }) => {
|
|
87
|
+
* onSubmit?.(text);
|
|
88
|
+
* setMessage('');
|
|
89
|
+
* }}
|
|
90
|
+
* />
|
|
91
|
+
* </KeyboardStickyView>
|
|
92
|
+
* );
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
FooterComponent?: React.FC | React.ReactNode;
|
|
97
|
+
/**
|
|
98
|
+
* Optional background component.
|
|
99
|
+
*
|
|
100
|
+
* ## Usage
|
|
101
|
+
*
|
|
102
|
+
* ```typescript
|
|
103
|
+
* function BackgroundComponent() {
|
|
104
|
+
* return (
|
|
105
|
+
* <View style={{ flex:1, backgroundColor: 'green' }} />
|
|
106
|
+
* );
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
BackgroundComponent?: React.FC | React.ReactNode;
|
|
111
|
+
children?: React.ReactNode;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* A comprehensive screen component that handles safe areas, scrolling and keyboard handling.
|
|
115
|
+
*
|
|
116
|
+
* ## Usage
|
|
117
|
+
*
|
|
118
|
+
* ```
|
|
119
|
+
* <ScreenContent
|
|
120
|
+
* scroll={true}
|
|
121
|
+
* edges={['bottom']}
|
|
122
|
+
* headerTransparent={false}
|
|
123
|
+
* scrollViewProps={{ bottomOffset: 40 }}
|
|
124
|
+
* contentContainerClassName="p-5 gap-3"
|
|
125
|
+
* >
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* ## Requirement
|
|
129
|
+
*
|
|
130
|
+
* Add [KeyboardProvider](https://kirillzyusko.github.io/react-native-keyboard-controller/docs/installation#adding-provider) as root app component.
|
|
131
|
+
*/
|
|
132
|
+
export declare const ScreenContent: React.ComponentType<BaseScreenContentProps & {
|
|
133
|
+
readonly className?: string | undefined;
|
|
134
|
+
readonly contentContainerClassName?: string | undefined;
|
|
135
|
+
}>;
|
|
136
|
+
export type ScreenContentProps = React.ComponentProps<typeof ScreenContent>;
|
|
137
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
export declare function useComponentNode(Component?: React.FC | React.ReactNode): React.ReactNode;
|
|
4
|
+
export declare function useFinalStyle(style: StyleProp<ViewStyle>, headerTransparent: boolean): StyleProp<ViewStyle>;
|
|
5
|
+
export declare function useFinalContentContainerStyle(contentContainerStyle: StyleProp<ViewStyle>, headerTransparent: boolean): StyleProp<ViewStyle>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type NavigationBarThemeConfig = {
|
|
2
|
+
light?: {
|
|
3
|
+
borderColor?: string;
|
|
4
|
+
backgroundColor?: string;
|
|
5
|
+
};
|
|
6
|
+
dark?: {
|
|
7
|
+
borderColor?: string;
|
|
8
|
+
backgroundColor?: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Makes Android navigation bar follow current color schema (light, dark) with optional color overrides.
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* Add this hook to root layout.
|
|
17
|
+
*
|
|
18
|
+
* ```
|
|
19
|
+
* useAndroidNavigationBar();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function useAndroidNavigationBar(config?: NavigationBarThemeConfig): void;
|
|
23
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mbrain/epic-react-native-lib",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "A set of helpful, battle-tested utilities that simplify common React Native workflows and speed up app development",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -34,8 +34,15 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@react-navigation/elements": "^2.9.1",
|
|
38
|
+
"expo-navigation-bar": "^5.0.10",
|
|
39
|
+
"expo-router": "^6.0.17",
|
|
37
40
|
"expo-screen-orientation": "^9.0.0",
|
|
38
|
-
"
|
|
41
|
+
"lodash": "^4.17.21",
|
|
42
|
+
"nativewind": "^4.2.1",
|
|
43
|
+
"react-native-keyboard-controller": "^1.20.1",
|
|
44
|
+
"react-native-mmkv": "^4.0.1",
|
|
45
|
+
"react-native-safe-area-context": "^5.6.2"
|
|
39
46
|
},
|
|
40
47
|
"peerDependencies": {
|
|
41
48
|
"react": ">=18.0.0",
|
|
@@ -52,6 +59,7 @@
|
|
|
52
59
|
}
|
|
53
60
|
},
|
|
54
61
|
"devDependencies": {
|
|
62
|
+
"@types/lodash": "^4.17.21",
|
|
55
63
|
"@types/react": "^19.2.5",
|
|
56
64
|
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
57
65
|
"@typescript-eslint/parser": "^8.46.4",
|