@chem-po/react-native 0.0.40 → 0.0.42

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.
Files changed (60) hide show
  1. package/lib/commonjs/components/button/DeleteButton.js +1 -1
  2. package/lib/commonjs/components/form/input/date/index.js +2 -2
  3. package/lib/commonjs/components/form/input/date/index.js.map +1 -1
  4. package/lib/commonjs/components/form/input/datetime/index.js +2 -2
  5. package/lib/commonjs/components/form/input/datetime/index.js.map +1 -1
  6. package/lib/commonjs/components/form/input/index.js +22 -0
  7. package/lib/commonjs/components/form/input/index.js.map +1 -1
  8. package/lib/commonjs/components/image/ImageViewModal.js +2 -1
  9. package/lib/commonjs/components/image/ImageViewModal.js.map +1 -1
  10. package/lib/commonjs/components/loading/CircularProgress.js +2 -1
  11. package/lib/commonjs/components/loading/CircularProgress.js.map +1 -1
  12. package/lib/commonjs/contexts/root.js +16 -20
  13. package/lib/commonjs/contexts/root.js.map +1 -1
  14. package/lib/commonjs/hooks/index.js +22 -0
  15. package/lib/commonjs/hooks/index.js.map +1 -1
  16. package/lib/commonjs/utils/downloadFile.js +34 -23
  17. package/lib/commonjs/utils/downloadFile.js.map +1 -1
  18. package/lib/commonjs/utils/downloadFileLegacy.js +64 -0
  19. package/lib/commonjs/utils/downloadFileLegacy.js.map +1 -0
  20. package/lib/module/components/button/DeleteButton.js +1 -1
  21. package/lib/module/components/form/input/date/index.js +2 -2
  22. package/lib/module/components/form/input/date/index.js.map +1 -1
  23. package/lib/module/components/form/input/datetime/index.js +2 -2
  24. package/lib/module/components/form/input/datetime/index.js.map +1 -1
  25. package/lib/module/components/form/input/index.js +2 -0
  26. package/lib/module/components/form/input/index.js.map +1 -1
  27. package/lib/module/components/image/ImageViewModal.js +2 -1
  28. package/lib/module/components/image/ImageViewModal.js.map +1 -1
  29. package/lib/module/components/loading/CircularProgress.js +3 -2
  30. package/lib/module/components/loading/CircularProgress.js.map +1 -1
  31. package/lib/module/contexts/root.js +17 -21
  32. package/lib/module/contexts/root.js.map +1 -1
  33. package/lib/module/hooks/index.js +2 -0
  34. package/lib/module/hooks/index.js.map +1 -1
  35. package/lib/module/utils/downloadFile.js +34 -22
  36. package/lib/module/utils/downloadFile.js.map +1 -1
  37. package/lib/module/utils/downloadFileLegacy.js +57 -0
  38. package/lib/module/utils/downloadFileLegacy.js.map +1 -0
  39. package/lib/typescript/components/form/input/index.d.ts +2 -0
  40. package/lib/typescript/components/form/input/index.d.ts.map +1 -1
  41. package/lib/typescript/components/image/ImageViewModal.d.ts.map +1 -1
  42. package/lib/typescript/components/loading/CircularProgress.d.ts.map +1 -1
  43. package/lib/typescript/contexts/root.d.ts +1 -1
  44. package/lib/typescript/contexts/root.d.ts.map +1 -1
  45. package/lib/typescript/hooks/index.d.ts +2 -0
  46. package/lib/typescript/hooks/index.d.ts.map +1 -1
  47. package/lib/typescript/utils/downloadFile.d.ts.map +1 -1
  48. package/lib/typescript/utils/downloadFileLegacy.d.ts +4 -0
  49. package/lib/typescript/utils/downloadFileLegacy.d.ts.map +1 -0
  50. package/package.json +27 -27
  51. package/src/components/button/DeleteButton.tsx +1 -1
  52. package/src/components/form/input/date/index.tsx +2 -2
  53. package/src/components/form/input/datetime/index.tsx +2 -2
  54. package/src/components/form/input/index.ts +2 -0
  55. package/src/components/image/ImageViewModal.tsx +2 -1
  56. package/src/components/loading/CircularProgress.tsx +3 -2
  57. package/src/contexts/root.tsx +31 -31
  58. package/src/hooks/index.ts +2 -0
  59. package/src/utils/downloadFile.ts +35 -20
  60. package/src/utils/downloadFileLegacy.ts +66 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ImageViewModal.d.ts","sourceRoot":"","sources":["../../../../src/components/image/ImageViewModal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAYxE,UAAU,mBAAmB;IAC3B,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA+OxD,CAAA"}
1
+ {"version":3,"file":"ImageViewModal.d.ts","sourceRoot":"","sources":["../../../../src/components/image/ImageViewModal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAaxE,UAAU,mBAAmB;IAC3B,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA+OxD,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../../../src/components/loading/CircularProgress.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAChD,OAAO,EAEL,sBAAsB,EAEtB,SAAS,EAET,SAAS,EACV,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,qBAAsB,SAAQ,sBAAsB;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IAChC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,gBAAgB,GAAI,gEAO9B,qBAAqB,sBAuBvB,CAAA"}
1
+ {"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../../../src/components/loading/CircularProgress.tsx"],"names":[],"mappings":"AACA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAChD,OAAO,EAEL,sBAAsB,EAEtB,SAAS,EAET,SAAS,EACV,MAAM,cAAc,CAAA;AAErB,MAAM,WAAW,qBAAsB,SAAQ,sBAAsB;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IAChC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,eAAO,MAAM,gBAAgB,GAAI,gEAO9B,qBAAqB,sBAwBvB,CAAA"}
@@ -13,5 +13,5 @@ export interface ChempoNativeProviderProps<BackendAdapter extends BackendAdapter
13
13
  middlewareProvider?: MiddlewareProvider;
14
14
  insetNotifier?: boolean;
15
15
  }
16
- export declare const ChempoNativeProvider: <BackendAdapter extends BackendAdapterInterface>({ theme: themeProp, initialColorMode, children, fonts, colorModeProp, middlewareProvider: Middleware, insetNotifier, ...props }: ChempoNativeProviderProps<BackendAdapter>) => React.JSX.Element;
16
+ export declare const ChempoNativeProvider: <BackendAdapter extends BackendAdapterInterface>({ theme: themeProp, initialColorMode, children, fonts: fontConfig, colorModeProp, middlewareProvider: Middleware, insetNotifier, ...props }: ChempoNativeProviderProps<BackendAdapter>) => React.JSX.Element;
17
17
  //# sourceMappingURL=root.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/contexts/root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACzE,OAAO,EAAE,WAAW,EAA4B,MAAM,gBAAgB,CAAA;AACtE,OAAO,KAAK,EAAE,EAAE,EAAE,EAAE,iBAAiB,EAAW,MAAM,OAAO,CAAA;AAG7D,OAAO,EAEL,eAAe,EAGhB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,OAAO,EAAgB,MAAM,yCAAyC,CAAA;AAS/E,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAC3E,MAAM,MAAM,kBAAkB,GAAG,EAAE,CAAC,iBAAiB,CAAC,CAAA;AACtD,MAAM,WAAW,yBAAyB,CAAC,cAAc,SAAS,uBAAuB,CACvF,SAAQ,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAAC,CAAC;IACzF,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,gBAAgB,CAAC,EAAE,SAAS,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAsHD,eAAO,MAAM,oBAAoB,GAAI,cAAc,SAAS,uBAAuB,EAAE,iIASlF,yBAAyB,CAAC,cAAc,CAAC,sBA0B3C,CAAA"}
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/contexts/root.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACzE,OAAO,EAAE,WAAW,EAAgC,MAAM,gBAAgB,CAAA;AAC1E,OAAO,KAAK,EAAE,EAAE,EAAE,EAAE,iBAAiB,EAAW,MAAM,OAAO,CAAA;AAG7D,OAAO,EAEL,eAAe,EAGhB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,OAAO,EAA2B,MAAM,yCAAyC,CAAA;AAS1F,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAC3E,MAAM,MAAM,kBAAkB,GAAG,EAAE,CAAC,iBAAiB,CAAC,CAAA;AACtD,MAAM,WAAW,yBAAyB,CAAC,cAAc,SAAS,uBAAuB,CACvF,SAAQ,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,gBAAgB,GAAG,QAAQ,CAAC,CAAC;IACzF,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,gBAAgB,CAAC,EAAE,SAAS,CAAA;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AA+GD,eAAO,MAAM,oBAAoB,GAAI,cAAc,SAAS,uBAAuB,EAAE,6IASlF,yBAAyB,CAAC,cAAc,CAAC,sBAiC3C,CAAA"}
@@ -1,2 +1,4 @@
1
+ export * from './useFadeIn';
2
+ export * from './useFont';
1
3
  export * from './useThemeState';
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"downloadFile.d.ts","sourceRoot":"","sources":["../../../src/utils/downloadFile.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,GAAU,KAAK,MAAM,EAAE,UAAU,MAAM,EAAE,UAAU,MAAM;;EAwCjF,CAAA"}
1
+ {"version":3,"file":"downloadFile.d.ts","sourceRoot":"","sources":["../../../src/utils/downloadFile.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,GAAU,KAAK,MAAM,EAAE,UAAU,MAAM,EAAE,UAAU,MAAM;;EAuDjF,CAAA"}
@@ -0,0 +1,4 @@
1
+ export declare const downloadFileLegacy: (uri: string, filename: string, fileType: string) => Promise<void | {
2
+ uri: string;
3
+ }>;
4
+ //# sourceMappingURL=downloadFileLegacy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloadFileLegacy.d.ts","sourceRoot":"","sources":["../../../src/utils/downloadFileLegacy.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,kBAAkB,GAAU,KAAK,MAAM,EAAE,UAAU,MAAM,EAAE,UAAU,MAAM;;EAqDvF,CAAA"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@chem-po/react-native",
3
3
  "author": "Elan Canfield",
4
4
  "license": "MIT",
5
- "version": "0.0.40",
5
+ "version": "0.0.42",
6
6
  "main": "lib/commonjs/index.js",
7
7
  "types": "lib/typescript/index.d.ts",
8
8
  "source": "src/index.ts",
@@ -30,50 +30,50 @@
30
30
  "!**/.*"
31
31
  ],
32
32
  "dependencies": {
33
- "@expo/vector-icons": "^14.0.4",
33
+ "@expo/vector-icons": "^15.0.2",
34
34
  "@lottiefiles/dotlottie-react": "^0.13.5",
35
- "@react-native-async-storage/async-storage": "2.1.2",
36
- "@react-native-community/slider": "4.5.6",
37
- "expo-constants": "~17.1.7",
38
- "expo-document-picker": "~13.1.6",
39
- "expo-file-system": "~18.1.11",
40
- "expo-image-picker": "~16.1.4",
41
- "expo-sharing": "~13.1.5",
42
- "lottie-react-native": "7.2.2",
35
+ "@react-native-async-storage/async-storage": "2.2.0",
36
+ "@react-native-community/slider": "5.0.1",
37
+ "expo-constants": "~18.0.9",
38
+ "expo-document-picker": "~14.0.7",
39
+ "expo-file-system": "~19.0.17",
40
+ "expo-image-picker": "~17.0.8",
41
+ "expo-sharing": "~14.0.7",
42
+ "lottie-react-native": "7.3.4",
43
43
  "nested-property": "^4.0.0",
44
- "react": "19.0.0",
45
44
  "react-hook-form": "^7.55.0",
46
- "react-native": "0.79.5",
45
+ "react-native": "0.81.4",
47
46
  "react-native-element-dropdown": "^2.12.4",
48
- "react-native-gesture-handler": "~2.24.0",
49
- "react-native-safe-area-context": "5.4.0",
50
- "react-native-reanimated": "~3.17.4",
47
+ "react-native-gesture-handler": "~2.28.0",
51
48
  "react-native-notifier": "^2.0.0",
52
49
  "react-native-paper": "^5.14.3",
53
50
  "react-native-paper-dates": "^0.22.42",
54
- "react-native-svg": "15.11.2",
51
+ "react-native-reanimated": "~4.1.1",
52
+ "react-native-safe-area-context": "5.6.1",
53
+ "react-native-svg": "15.12.1",
54
+ "react-native-worklets": "0.5.1",
55
55
  "zustand": "^4.3.3",
56
- "@chem-po/core": "0.0.40",
57
- "@chem-po/react": "0.0.40"
56
+ "@chem-po/core": "0.0.42",
57
+ "@chem-po/react": "0.0.42"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@babel/core": "^7.26.0",
61
61
  "@babel/preset-env": "^7.25.4",
62
- "@expo/metro-runtime": "~5.0.4",
63
- "@types/react": "~19.0.12",
62
+ "@expo/metro-runtime": "~6.1.2",
63
+ "@types/react": "~19.1.0",
64
64
  "babel-plugin-react-docgen-typescript": "^1.5.1",
65
65
  "babel-plugin-react-native-web": "^0.19.10",
66
- "expo-build-properties": "~0.14.6",
67
- "expo-dev-client": "~5.2.0",
68
- "eslint-config-expo": "~9.2.0",
66
+ "eslint-config-expo": "~10.0.0",
67
+ "expo-build-properties": "~1.0.9",
68
+ "expo-dev-client": "~6.0.15",
69
69
  "react-native-builder-bob": "^0.20.0",
70
70
  "vite": "^6.2.2"
71
71
  },
72
72
  "peerDependencies": {
73
- "expo": "~53.0.22",
74
- "react": "19.0.0",
75
- "react-dom": "19.0.0",
76
- "react-native": "0.79.4"
73
+ "expo": "~54.0.0",
74
+ "react": "~19.1.0",
75
+ "react-dom": "~19.1.0",
76
+ "react-native": "~0.81.0"
77
77
  },
78
78
  "react-native-builder-bob": {
79
79
  "source": "src",
@@ -93,7 +93,7 @@ export const DeleteButton: React.FC<DeleteButtonProps> = ({
93
93
  const [confirmActive, setConfirmActive] = useState(false)
94
94
  const confirmTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
95
95
  const isMounted = useRef(true)
96
- const defaultColor = useColorModeValue('#dd2222', '#ff7777')
96
+ const defaultColor = useColorModeValue('#dd4444', '#ff4444')
97
97
  const color = colorProp ?? defaultColor
98
98
 
99
99
  useEffect(() => {
@@ -6,7 +6,7 @@ import { StyleSheet, Text, View } from 'react-native'
6
6
  import { Gesture, GestureDetector } from 'react-native-gesture-handler'
7
7
  import { Portal } from 'react-native-paper'
8
8
  import { DatePickerModal } from 'react-native-paper-dates'
9
- import { runOnJS } from 'react-native-reanimated'
9
+ import { scheduleOnRN } from 'react-native-worklets'
10
10
  import { FieldProps } from '../../types'
11
11
  import { DateInputClearButton } from '../common/InputClearButton'
12
12
  import { useInputColor } from '../hooks/useInputColor'
@@ -55,7 +55,7 @@ export const DateInput = forwardRef<InputRef, FieldProps<DateField>>(
55
55
  const maxDateObj = maxDate === 'now' ? new Date() : maxDate ? new Date(maxDate) : undefined
56
56
 
57
57
  const mainTap = Gesture.Tap().onStart(() => {
58
- runOnJS(onFocus)()
58
+ scheduleOnRN(onFocus)
59
59
  })
60
60
 
61
61
  return (
@@ -6,7 +6,7 @@ import { StyleSheet, Text, View } from 'react-native'
6
6
  import { Gesture, GestureDetector, Pressable } from 'react-native-gesture-handler'
7
7
  import { Portal } from 'react-native-paper'
8
8
  import { DatePickerModal, TimePickerModal } from 'react-native-paper-dates'
9
- import { runOnJS } from 'react-native-reanimated'
9
+ import { scheduleOnRN } from 'react-native-worklets'
10
10
  import { FieldProps } from '../../types'
11
11
  import { DateInputClearButton } from '../common/InputClearButton'
12
12
  import { useInputColor } from '../hooks/useInputColor'
@@ -96,7 +96,7 @@ export const DateTimeInput = forwardRef<InputRef, FieldProps<DateTimeField>>(
96
96
  const inputColor = useInputColor(value)
97
97
 
98
98
  const mainTap = Gesture.Tap().onStart(() => {
99
- runOnJS(handleFocusDate)()
99
+ scheduleOnRN(handleFocusDate)
100
100
  })
101
101
 
102
102
  return (
@@ -1,2 +1,4 @@
1
1
  export * from './Editable'
2
+ export * from './hooks'
3
+ export * from './input'
2
4
  export * from './StandaloneInput'
@@ -1,7 +1,7 @@
1
1
  import { useScreen, useToast } from '@chem-po/react'
2
2
  import { Ionicons } from '@expo/vector-icons'
3
3
  import React, { useCallback, useEffect, useMemo, useState } from 'react'
4
- import { Image, Modal, Platform, SafeAreaView, StyleSheet, View } from 'react-native'
4
+ import { Image, Modal, Platform, StyleSheet, View } from 'react-native'
5
5
  import {
6
6
  Gesture,
7
7
  GestureDetector,
@@ -9,6 +9,7 @@ import {
9
9
  Pressable,
10
10
  } from 'react-native-gesture-handler'
11
11
  import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'
12
+ import { SafeAreaView } from 'react-native-safe-area-context'
12
13
  import { downloadFile } from '../../utils/downloadFile'
13
14
  import { LoadingLogo } from '../loading/Loading'
14
15
 
@@ -1,4 +1,4 @@
1
- import { useColorModeValue } from '@chem-po/react'
1
+ import { useBackgroundColor, useColorModeValue } from '@chem-po/react'
2
2
  import React, { useEffect, useRef } from 'react'
3
3
  import {
4
4
  ActivityIndicator,
@@ -24,6 +24,7 @@ export const CircularProgress = ({
24
24
  ...props
25
25
  }: CircularProgressProps) => {
26
26
  const defaultTrackColor = useColorModeValue('#959595', '#575757')
27
+ const defaultColor = useBackgroundColor(750)
27
28
  const opacity = useRef(new Animated.Value(visible ? 1 : 0)).current
28
29
 
29
30
  useEffect(() => {
@@ -42,7 +43,7 @@ export const CircularProgress = ({
42
43
  {...props}
43
44
  />
44
45
  {/* Spinning circle */}
45
- <ActivityIndicator animating={animating} color={color ?? '#575757'} {...props} />
46
+ <ActivityIndicator animating={animating} color={color ?? defaultColor} {...props} />
46
47
  </Animated.View>
47
48
  )
48
49
  }
@@ -1,5 +1,5 @@
1
1
  import { BackendAdapterInterface, ColorMode, Theme } from '@chem-po/core'
2
- import { ChempoProps, ChempoProvider, useTheme } from '@chem-po/react'
2
+ import { ChempoProps, ChempoProvider, defaultTheme } from '@chem-po/react'
3
3
  import React, { FC, PropsWithChildren, useMemo } from 'react'
4
4
  import { GestureHandlerRootView } from 'react-native-gesture-handler'
5
5
  import { NotifierWrapper } from 'react-native-notifier'
@@ -10,7 +10,7 @@ import {
10
10
  Props as PaperProviderProps,
11
11
  } from 'react-native-paper'
12
12
  import { en, registerTranslation } from 'react-native-paper-dates'
13
- import { MD3Type, MD3Typescale } from 'react-native-paper/lib/typescript/types'
13
+ import { MD3Type, MD3Typescale, ThemeProp } from 'react-native-paper/lib/typescript/types'
14
14
  import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
15
15
  import { nativeToast } from '../constants/toast'
16
16
  import { UseThemeProps, useThemeState } from '../hooks/useThemeState'
@@ -116,30 +116,23 @@ const createPaperTheme = (
116
116
 
117
117
  const ChempoPaperProvider = ({
118
118
  children,
119
- fonts: fontConfig,
120
- }: PropsWithChildren<{ fonts?: FontConfig }>) => {
121
- const { theme, colorMode } = useTheme()
122
-
123
- const { theme: paperTheme, fonts } = useMemo(
124
- () => createPaperTheme(theme, fontConfig, colorMode),
125
- [theme, fontConfig, colorMode],
126
- )
127
- return (
128
- <ChempoFontsProvider fonts={fonts}>
129
- <PaperProvider theme={paperTheme}>{children}</PaperProvider>
130
- </ChempoFontsProvider>
131
- )
119
+ paperTheme,
120
+ }: PropsWithChildren<{ paperTheme: ThemeProp | undefined }>) => {
121
+ return <PaperProvider theme={paperTheme}>{children}</PaperProvider>
132
122
  }
133
123
 
134
124
  const ProviderBody = ({
135
125
  children,
136
- fonts,
137
126
  insetNotifier,
138
- }: PropsWithChildren<{ fonts?: FontConfig; insetNotifier?: boolean }>) => {
127
+ paperTheme,
128
+ }: PropsWithChildren<{
129
+ insetNotifier?: boolean
130
+ paperTheme: ThemeProp | undefined
131
+ }>) => {
139
132
  const { top } = useSafeAreaInsets()
140
133
 
141
134
  return (
142
- <ChempoPaperProvider fonts={fonts}>
135
+ <ChempoPaperProvider paperTheme={paperTheme}>
143
136
  <NotifierWrapper containerStyle={{ paddingTop: insetNotifier ? top : 0 }}>
144
137
  {children}
145
138
  </NotifierWrapper>
@@ -151,7 +144,7 @@ export const ChempoNativeProvider = <BackendAdapter extends BackendAdapterInterf
151
144
  theme: themeProp,
152
145
  initialColorMode,
153
146
  children,
154
- fonts,
147
+ fonts: fontConfig,
155
148
  colorModeProp,
156
149
  middlewareProvider: Middleware,
157
150
  insetNotifier,
@@ -163,23 +156,30 @@ export const ChempoNativeProvider = <BackendAdapter extends BackendAdapterInterf
163
156
  )
164
157
  const theme = useThemeState(useThemeProps)
165
158
 
159
+ const { theme: paperTheme, fonts } = useMemo(
160
+ () => createPaperTheme(theme.theme ?? defaultTheme, fontConfig, theme.colorMode),
161
+ [theme, fontConfig],
162
+ )
163
+
166
164
  const body = (
167
- <ProviderBody insetNotifier={insetNotifier} fonts={fonts}>
165
+ <ProviderBody insetNotifier={insetNotifier} paperTheme={paperTheme}>
168
166
  {children}
169
167
  </ProviderBody>
170
168
  )
171
169
 
172
170
  return (
173
- <ChempoProvider
174
- toast={nativeToast}
175
- theme={theme}
176
- initializeScreen={initializeScreen}
177
- {...props}>
178
- <SafeAreaProvider>
179
- <GestureHandlerRootView>
180
- {Middleware ? <Middleware>{body}</Middleware> : body}
181
- </GestureHandlerRootView>
182
- </SafeAreaProvider>
183
- </ChempoProvider>
171
+ <ChempoFontsProvider fonts={fonts}>
172
+ <ChempoProvider
173
+ toast={nativeToast}
174
+ theme={theme}
175
+ initializeScreen={initializeScreen}
176
+ {...props}>
177
+ <SafeAreaProvider>
178
+ <GestureHandlerRootView>
179
+ {Middleware ? <Middleware>{body}</Middleware> : body}
180
+ </GestureHandlerRootView>
181
+ </SafeAreaProvider>
182
+ </ChempoProvider>
183
+ </ChempoFontsProvider>
184
184
  )
185
185
  }
@@ -1 +1,3 @@
1
+ export * from './useFadeIn'
2
+ export * from './useFont'
1
3
  export * from './useThemeState'
@@ -1,46 +1,61 @@
1
- import * as FileSystem from 'expo-file-system'
2
- import { downloadAsync } from 'expo-file-system'
1
+ import { Directory, File, Paths } from 'expo-file-system'
2
+ import { StorageAccessFramework } from 'expo-file-system/legacy'
3
3
  import { shareAsync } from 'expo-sharing'
4
4
  import { Platform } from 'react-native'
5
5
 
6
6
  export const downloadFile = async (uri: string, filename: string, fileType: string) => {
7
7
  if (Platform.OS === 'android') {
8
- const permissions = await FileSystem.StorageAccessFramework.requestDirectoryPermissionsAsync()
8
+ const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync()
9
9
  if (!permissions.granted) {
10
10
  throw new Error('Permission not granted')
11
11
  }
12
12
 
13
- // Download to temporary location first
14
- const tempFileUri = `${FileSystem.cacheDirectory}${filename}`
13
+ // Create cache directory for temporary file
14
+ const cacheDir = new Directory(Paths.cache)
15
15
 
16
- // Download the file to temporary location
17
- await FileSystem.downloadAsync(uri, tempFileUri)
16
+ // Ensure cache directory exists
17
+ if (!cacheDir.exists) {
18
+ cacheDir.create()
19
+ }
18
20
 
19
- // Read the temporary file as base64
20
- const base64Content = await FileSystem.readAsStringAsync(tempFileUri, {
21
- encoding: FileSystem.EncodingType.Base64,
22
- })
21
+ // Download the file to cache directory using static method
22
+ const downloadedFile = await File.downloadFileAsync(uri, cacheDir)
23
+
24
+ // Read the downloaded file as bytes and convert to base64
25
+ const fileBytes = await downloadedFile.bytes()
26
+
27
+ // Convert Uint8Array to base64 safely (handles large files better than btoa)
28
+ const base64Content = Array.from(fileBytes, byte => String.fromCharCode(byte)).join('')
29
+ const encodedContent = btoa(base64Content)
23
30
 
24
31
  // Create a file within the selected directory using SAF
25
- const fileUri = await FileSystem.StorageAccessFramework.createFileAsync(
32
+ const fileUri = await StorageAccessFramework.createFileAsync(
26
33
  permissions.directoryUri,
27
34
  filename,
28
35
  fileType,
29
36
  )
30
37
 
31
- // Write the content to the SAF file
32
- await FileSystem.StorageAccessFramework.writeAsStringAsync(fileUri, base64Content, {
33
- encoding: FileSystem.EncodingType.Base64,
38
+ // Write the content to the SAF file using legacy method (as SAF might not have new API yet)
39
+ await StorageAccessFramework.writeAsStringAsync(fileUri, encodedContent, {
40
+ encoding: 'base64',
34
41
  })
35
42
 
36
43
  // Clean up temporary file
37
- await FileSystem.deleteAsync(tempFileUri, { idempotent: true })
44
+ downloadedFile.delete()
38
45
 
39
46
  return { uri: fileUri }
40
47
  }
41
- if (!FileSystem.documentDirectory) {
42
- throw new Error('Document directory not found')
48
+
49
+ // For iOS and other platforms
50
+ const documentsDir = new Directory(Paths.document)
51
+
52
+ // Ensure documents directory exists
53
+ if (!documentsDir.exists) {
54
+ documentsDir.create()
43
55
  }
44
- const result = await downloadAsync(uri, FileSystem.documentDirectory + filename)
45
- return shareAsync(result.uri)
56
+
57
+ // Download file directly to documents directory
58
+ const downloadedFile = await File.downloadFileAsync(uri, documentsDir)
59
+
60
+ return shareAsync(downloadedFile.uri)
46
61
  }
@@ -0,0 +1,66 @@
1
+ import {
2
+ cacheDirectory,
3
+ deleteAsync,
4
+ documentDirectory,
5
+ downloadAsync,
6
+ EncodingType,
7
+ readAsStringAsync,
8
+ StorageAccessFramework,
9
+ } from 'expo-file-system/legacy'
10
+ import { shareAsync } from 'expo-sharing'
11
+ import { Platform } from 'react-native'
12
+
13
+ export const downloadFileLegacy = async (uri: string, filename: string, fileType: string) => {
14
+ if (Platform.OS === 'android') {
15
+ const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync()
16
+ if (!permissions.granted) {
17
+ throw new Error('Permission not granted')
18
+ }
19
+
20
+ // Download to temporary location first
21
+ const tempFileUri = `${cacheDirectory}${filename}`
22
+
23
+ try {
24
+ // Download the file to temporary location
25
+ await downloadAsync(uri, tempFileUri)
26
+
27
+ // Read the temporary file as base64
28
+ const base64Content = await readAsStringAsync(tempFileUri, {
29
+ encoding: EncodingType.Base64,
30
+ })
31
+
32
+ // Create a file within the selected directory using SAF
33
+ const fileUri = await StorageAccessFramework.createFileAsync(
34
+ permissions.directoryUri,
35
+ filename,
36
+ fileType,
37
+ )
38
+
39
+ // Write the content to the SAF file
40
+ await StorageAccessFramework.writeAsStringAsync(fileUri, base64Content, {
41
+ encoding: EncodingType.Base64,
42
+ })
43
+
44
+ // Clean up temporary file
45
+ await deleteAsync(tempFileUri, { idempotent: true })
46
+
47
+ return { uri: fileUri }
48
+ } catch (error) {
49
+ // Clean up temporary file in case of error
50
+ try {
51
+ await deleteAsync(tempFileUri, { idempotent: true })
52
+ } catch {
53
+ // Ignore cleanup errors
54
+ }
55
+ throw error
56
+ }
57
+ }
58
+
59
+ // For iOS and other platforms
60
+ if (!documentDirectory) {
61
+ throw new Error('Document directory not found')
62
+ }
63
+
64
+ const result = await downloadAsync(uri, documentDirectory + filename)
65
+ return shareAsync(result.uri)
66
+ }