@chem-po/react-native 0.0.52 → 0.0.53
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/package.json +5 -20
- package/src/components/box/Center.tsx +0 -19
- package/src/components/box/CollapseHorizontal.tsx +0 -44
- package/src/components/box/ContentBox.tsx +0 -24
- package/src/components/box/DropShadow.tsx +0 -28
- package/src/components/box/ExpandOnMount.tsx +0 -74
- package/src/components/box/Expandable.tsx +0 -143
- package/src/components/box/FullSizeContainer.tsx +0 -64
- package/src/components/box/index.ts +0 -7
- package/src/components/button/ActionButton.tsx +0 -196
- package/src/components/button/ButtonText.tsx +0 -60
- package/src/components/button/DeleteButton.tsx +0 -288
- package/src/components/button/LoadingButton.tsx +0 -41
- package/src/components/button/Toggle.tsx +0 -109
- package/src/components/button/hooks.ts +0 -66
- package/src/components/button/index.ts +0 -5
- package/src/components/feed/FeedContentPane.tsx +0 -97
- package/src/components/feed/MediaFeed.tsx +0 -199
- package/src/components/feed/MediaFeedBackground.tsx +0 -136
- package/src/components/feed/MediaFeedRefresh.tsx +0 -113
- package/src/components/feed/constants.ts +0 -2
- package/src/components/feed/context.tsx +0 -19
- package/src/components/feed/hooks.ts +0 -279
- package/src/components/feed/index.ts +0 -2
- package/src/components/form/Condition.tsx +0 -27
- package/src/components/form/Field.tsx +0 -44
- package/src/components/form/Form.tsx +0 -452
- package/src/components/form/FormFooter.tsx +0 -164
- package/src/components/form/UploadProgress/index.tsx +0 -50
- package/src/components/form/index.ts +0 -3
- package/src/components/form/input/Editable.tsx +0 -206
- package/src/components/form/input/InputSlider.tsx +0 -71
- package/src/components/form/input/OptionalTag.tsx +0 -43
- package/src/components/form/input/StandaloneInput.tsx +0 -49
- package/src/components/form/input/boolean/index.tsx +0 -53
- package/src/components/form/input/color/index.tsx +0 -145
- package/src/components/form/input/common/InputClearButton.tsx +0 -57
- package/src/components/form/input/date/index.tsx +0 -125
- package/src/components/form/input/datetime/index.tsx +0 -176
- package/src/components/form/input/file/index.tsx +0 -310
- package/src/components/form/input/hooks/index.ts +0 -2
- package/src/components/form/input/hooks/useInputColor.ts +0 -7
- package/src/components/form/input/hooks/useInputImperativeHandle.ts +0 -22
- package/src/components/form/input/hooks/useInputStyles.ts +0 -114
- package/src/components/form/input/index.ts +0 -4
- package/src/components/form/input/input.tsx +0 -218
- package/src/components/form/input/multipleSelect/index.tsx +0 -221
- package/src/components/form/input/number/index.tsx +0 -108
- package/src/components/form/input/select/index.tsx +0 -152
- package/src/components/form/input/socialMedia/index.tsx +0 -235
- package/src/components/form/input/text/AutoResizeTextarea.tsx +0 -41
- package/src/components/form/input/text/index.tsx +0 -99
- package/src/components/form/input/text/textarea.tsx +0 -32
- package/src/components/form/input/text/useWebAutoResize.tsx +0 -73
- package/src/components/form/input/time/index.tsx +0 -125
- package/src/components/form/types.ts +0 -8
- package/src/components/form/view/file.tsx +0 -80
- package/src/components/form/view/index.tsx +0 -125
- package/src/components/form/view/multipleSelect.tsx +0 -85
- package/src/components/form/view/select.tsx +0 -83
- package/src/components/form/view/styles.ts +0 -12
- package/src/components/icons/index.tsx +0 -28
- package/src/components/image/ImageViewModal.tsx +0 -319
- package/src/components/image/index.ts +0 -1
- package/src/components/index.ts +0 -8
- package/src/components/layout/CollapseHorizontal.tsx +0 -92
- package/src/components/loading/CircularProgress.tsx +0 -56
- package/src/components/loading/Loading.tsx +0 -146
- package/src/components/loading/LoadingImage.tsx +0 -163
- package/src/components/loading/LoadingOverlay.tsx +0 -74
- package/src/components/loading/LoadingSwitch.tsx +0 -110
- package/src/components/loading/ProgressBar.tsx +0 -75
- package/src/components/loading/index.ts +0 -6
- package/src/components/text/AnimatedText.tsx +0 -68
- package/src/components/text/Txt.tsx +0 -12
- package/src/components/text/index.ts +0 -1
- package/src/components/theme/colorMode/DarkModeToggle.tsx +0 -47
- package/src/components/theme/colorMode/index.ts +0 -1
- package/src/components/theme/index.ts +0 -1
- package/src/constants/index.ts +0 -1
- package/src/constants/toast.ts +0 -24
- package/src/contexts/fonts.tsx +0 -23
- package/src/contexts/index.ts +0 -1
- package/src/contexts/root.tsx +0 -190
- package/src/hooks/index.ts +0 -3
- package/src/hooks/useFadeIn.ts +0 -48
- package/src/hooks/useFont.ts +0 -25
- package/src/hooks/useRefreshFontScale.ts +0 -39
- package/src/hooks/useThemeState.ts +0 -43
- package/src/index.ts +0 -6
- package/src/store/index.ts +0 -2
- package/src/store/useFontScale.ts +0 -8
- package/src/store/useScreen.ts +0 -25
- package/src/styles/fill.ts +0 -19
- package/src/types/forms.ts +0 -14
- package/src/types/index.ts +0 -1
- package/src/utils/downloadFile.ts +0 -61
- package/src/utils/downloadFileLegacy.ts +0 -66
package/src/contexts/root.tsx
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { BackendAdapterInterface, ColorMode, Theme } from '@chem-po/core'
|
|
2
|
-
import { ChempoProps, ChempoProvider, defaultTheme } from '@chem-po/react'
|
|
3
|
-
import React, { FC, PropsWithChildren, useMemo } from 'react'
|
|
4
|
-
import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
|
5
|
-
import { NotifierWrapper } from 'react-native-notifier'
|
|
6
|
-
import {
|
|
7
|
-
configureFonts,
|
|
8
|
-
MD3TypescaleKey,
|
|
9
|
-
PaperProvider,
|
|
10
|
-
Props as PaperProviderProps,
|
|
11
|
-
} from 'react-native-paper'
|
|
12
|
-
import { en, registerTranslation } from 'react-native-paper-dates'
|
|
13
|
-
import { MD3Type, MD3Typescale, ThemeProp } from 'react-native-paper/lib/typescript/types'
|
|
14
|
-
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
15
|
-
import { nativeToast } from '../constants/toast'
|
|
16
|
-
import { useRefreshFontScale } from '../hooks/useRefreshFontScale'
|
|
17
|
-
import { UseThemeProps, useThemeState } from '../hooks/useThemeState'
|
|
18
|
-
import { initializeScreen } from '../store/useScreen'
|
|
19
|
-
import { ChempoFontsProvider } from './fonts'
|
|
20
|
-
|
|
21
|
-
registerTranslation('en', en)
|
|
22
|
-
|
|
23
|
-
export type FontConfig = Partial<Record<MD3TypescaleKey, Partial<MD3Type>>>
|
|
24
|
-
export type MiddlewareProvider = FC<PropsWithChildren>
|
|
25
|
-
export interface ChempoNativeProviderProps<
|
|
26
|
-
BackendAdapter extends BackendAdapterInterface,
|
|
27
|
-
> extends PropsWithChildren<Pick<ChempoProps<BackendAdapter>, 'backendAdapter' | 'assets'>> {
|
|
28
|
-
theme?: Theme
|
|
29
|
-
fonts?: FontConfig
|
|
30
|
-
initialColorMode?: ColorMode
|
|
31
|
-
colorModeProp?: string
|
|
32
|
-
middlewareProvider?: MiddlewareProvider
|
|
33
|
-
insetNotifier?: boolean
|
|
34
|
-
disableFontScaling?: boolean
|
|
35
|
-
}
|
|
36
|
-
const createPaperTheme = (
|
|
37
|
-
themeConfig: Theme,
|
|
38
|
-
font: FontConfig | undefined,
|
|
39
|
-
colorMode: ColorMode,
|
|
40
|
-
): { theme: PaperProviderProps['theme']; fonts: MD3Typescale } => {
|
|
41
|
-
const { colors } = themeConfig
|
|
42
|
-
|
|
43
|
-
const fonts = configureFonts({
|
|
44
|
-
config: {
|
|
45
|
-
...font,
|
|
46
|
-
bodyLarge: {
|
|
47
|
-
fontSize: 18,
|
|
48
|
-
...font?.bodyLarge,
|
|
49
|
-
},
|
|
50
|
-
bodyMedium: {
|
|
51
|
-
fontSize: 17,
|
|
52
|
-
...font?.bodyMedium,
|
|
53
|
-
},
|
|
54
|
-
bodySmall: {
|
|
55
|
-
fontSize: 16,
|
|
56
|
-
...font?.bodySmall,
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
})
|
|
60
|
-
const theme = {
|
|
61
|
-
dark: colorMode === 'dark',
|
|
62
|
-
colors: {
|
|
63
|
-
primary: colors.accent[300],
|
|
64
|
-
onPrimary: colors.text[900],
|
|
65
|
-
primaryContainer: colors.accent[800],
|
|
66
|
-
onPrimaryContainer: colors.text[150],
|
|
67
|
-
|
|
68
|
-
secondary: colors.background[150],
|
|
69
|
-
onSecondary: colors.text[100],
|
|
70
|
-
secondaryContainer: colors.accent[950],
|
|
71
|
-
onSecondaryContainer: colors.text[150],
|
|
72
|
-
|
|
73
|
-
tertiary: colors.accent[600],
|
|
74
|
-
onTertiary: colors.text[50],
|
|
75
|
-
tertiaryContainer: colors.accent[300],
|
|
76
|
-
onTertiaryContainer: colors.text[700],
|
|
77
|
-
|
|
78
|
-
error: colors.error[500],
|
|
79
|
-
onError: colors.text[50],
|
|
80
|
-
errorContainer: colors.error[100],
|
|
81
|
-
onErrorContainer: colors.error[900],
|
|
82
|
-
|
|
83
|
-
background: colors.background[50],
|
|
84
|
-
onBackground: colors.text[100],
|
|
85
|
-
surface: colors.background[100],
|
|
86
|
-
onSurface: colors.text[100],
|
|
87
|
-
surfaceVariant: colors.background[200],
|
|
88
|
-
onSurfaceVariant: colors.text[300],
|
|
89
|
-
outline: colors.text[500],
|
|
90
|
-
outlineVariant: colors.accent[300],
|
|
91
|
-
|
|
92
|
-
surfaceDisabled: colors.background[200],
|
|
93
|
-
onSurfaceDisabled: colors.text[400],
|
|
94
|
-
backdrop: '#000000aa', // 60% opacity
|
|
95
|
-
|
|
96
|
-
inverseSurface: colors.background[900],
|
|
97
|
-
inverseOnSurface: colors.text[50],
|
|
98
|
-
inversePrimary: colors.accent[200],
|
|
99
|
-
shadow: '#00000099',
|
|
100
|
-
scrim: '#00000099', // Semi-transparent dark overlay
|
|
101
|
-
|
|
102
|
-
elevation: {
|
|
103
|
-
level0: 'transparent',
|
|
104
|
-
level1: colors.background[100],
|
|
105
|
-
level2: colors.background[200],
|
|
106
|
-
level3: colors.background[300],
|
|
107
|
-
level4: colors.background[400],
|
|
108
|
-
level5: colors.background[500],
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
roundness: 4,
|
|
112
|
-
animation: {
|
|
113
|
-
scale: 1.0,
|
|
114
|
-
},
|
|
115
|
-
fonts,
|
|
116
|
-
}
|
|
117
|
-
return { theme, fonts }
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const ChempoPaperProvider = ({
|
|
121
|
-
children,
|
|
122
|
-
paperTheme,
|
|
123
|
-
}: PropsWithChildren<{ paperTheme: ThemeProp | undefined }>) => {
|
|
124
|
-
return <PaperProvider theme={paperTheme}>{children}</PaperProvider>
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const ProviderBody = ({
|
|
128
|
-
children,
|
|
129
|
-
insetNotifier,
|
|
130
|
-
paperTheme,
|
|
131
|
-
}: PropsWithChildren<{
|
|
132
|
-
insetNotifier?: boolean
|
|
133
|
-
paperTheme: ThemeProp | undefined
|
|
134
|
-
}>) => {
|
|
135
|
-
const { top } = useSafeAreaInsets()
|
|
136
|
-
|
|
137
|
-
return (
|
|
138
|
-
<ChempoPaperProvider paperTheme={paperTheme}>
|
|
139
|
-
<NotifierWrapper containerStyle={{ paddingTop: insetNotifier ? top : 0 }}>
|
|
140
|
-
{children}
|
|
141
|
-
</NotifierWrapper>
|
|
142
|
-
</ChempoPaperProvider>
|
|
143
|
-
)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export const ChempoNativeProvider = <BackendAdapter extends BackendAdapterInterface>({
|
|
147
|
-
theme: themeProp,
|
|
148
|
-
initialColorMode,
|
|
149
|
-
children,
|
|
150
|
-
fonts: fontConfig,
|
|
151
|
-
colorModeProp,
|
|
152
|
-
middlewareProvider: Middleware,
|
|
153
|
-
insetNotifier,
|
|
154
|
-
disableFontScaling,
|
|
155
|
-
...props
|
|
156
|
-
}: ChempoNativeProviderProps<BackendAdapter>) => {
|
|
157
|
-
const useThemeProps = useMemo<UseThemeProps>(
|
|
158
|
-
() => ({ theme: themeProp, initialColorMode, colorModeProp }),
|
|
159
|
-
[themeProp, initialColorMode, colorModeProp],
|
|
160
|
-
)
|
|
161
|
-
const theme = useThemeState(useThemeProps)
|
|
162
|
-
useRefreshFontScale(disableFontScaling)
|
|
163
|
-
|
|
164
|
-
const { theme: paperTheme, fonts } = useMemo(
|
|
165
|
-
() => createPaperTheme(theme.theme ?? defaultTheme, fontConfig, theme.colorMode),
|
|
166
|
-
[theme, fontConfig],
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
const body = (
|
|
170
|
-
<ProviderBody insetNotifier={insetNotifier} paperTheme={paperTheme}>
|
|
171
|
-
{children}
|
|
172
|
-
</ProviderBody>
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
return (
|
|
176
|
-
<ChempoFontsProvider fonts={fonts}>
|
|
177
|
-
<ChempoProvider
|
|
178
|
-
toast={nativeToast}
|
|
179
|
-
theme={theme}
|
|
180
|
-
initializeScreen={initializeScreen}
|
|
181
|
-
{...props}>
|
|
182
|
-
<SafeAreaProvider>
|
|
183
|
-
<GestureHandlerRootView>
|
|
184
|
-
{Middleware ? <Middleware>{body}</Middleware> : body}
|
|
185
|
-
</GestureHandlerRootView>
|
|
186
|
-
</SafeAreaProvider>
|
|
187
|
-
</ChempoProvider>
|
|
188
|
-
</ChempoFontsProvider>
|
|
189
|
-
)
|
|
190
|
-
}
|
package/src/hooks/index.ts
DELETED
package/src/hooks/useFadeIn.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef } from 'react'
|
|
2
|
-
import { Animated } from 'react-native'
|
|
3
|
-
|
|
4
|
-
export interface FadeInOptions {
|
|
5
|
-
activeOpacity?: number
|
|
6
|
-
inactiveOpacity?: number
|
|
7
|
-
duration?: number
|
|
8
|
-
enterDelay?: number
|
|
9
|
-
exitDelay?: number
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const defaultFadeInOptions: FadeInOptions = {
|
|
13
|
-
activeOpacity: 1,
|
|
14
|
-
inactiveOpacity: 0,
|
|
15
|
-
duration: 250,
|
|
16
|
-
enterDelay: 0,
|
|
17
|
-
exitDelay: 0,
|
|
18
|
-
}
|
|
19
|
-
export const useFadeIn = (active: boolean, opts?: FadeInOptions) => {
|
|
20
|
-
const {
|
|
21
|
-
activeOpacity = 1,
|
|
22
|
-
inactiveOpacity = 0,
|
|
23
|
-
duration = 300,
|
|
24
|
-
enterDelay = 0,
|
|
25
|
-
exitDelay = 0,
|
|
26
|
-
} = opts ?? defaultFadeInOptions
|
|
27
|
-
const opacity = useRef(new Animated.Value(active ? activeOpacity : inactiveOpacity))
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
if (active) {
|
|
31
|
-
Animated.timing(opacity.current, {
|
|
32
|
-
toValue: activeOpacity,
|
|
33
|
-
duration,
|
|
34
|
-
useNativeDriver: true,
|
|
35
|
-
delay: enterDelay,
|
|
36
|
-
}).start()
|
|
37
|
-
} else {
|
|
38
|
-
Animated.timing(opacity.current, {
|
|
39
|
-
toValue: inactiveOpacity,
|
|
40
|
-
duration,
|
|
41
|
-
useNativeDriver: true,
|
|
42
|
-
delay: exitDelay,
|
|
43
|
-
}).start()
|
|
44
|
-
}
|
|
45
|
-
}, [active, activeOpacity, inactiveOpacity, duration, enterDelay, exitDelay])
|
|
46
|
-
|
|
47
|
-
return opacity.current
|
|
48
|
-
}
|
package/src/hooks/useFont.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { useChempoFonts } from '../contexts/fonts'
|
|
2
|
-
|
|
3
|
-
export type FontFamilyType = 'display' | 'body' | 'label' | 'headline' | 'title'
|
|
4
|
-
export type FontSize = 'lg' | 'md' | 'sm'
|
|
5
|
-
export type FontSizeKey = 'Small' | 'Medium' | 'Large'
|
|
6
|
-
export type FontKey = `${FontFamilyType}${FontSizeKey}`
|
|
7
|
-
|
|
8
|
-
const getFontKeySize = (fontSize: FontSize): FontSizeKey => {
|
|
9
|
-
switch (fontSize) {
|
|
10
|
-
case 'lg':
|
|
11
|
-
return 'Large'
|
|
12
|
-
case 'md':
|
|
13
|
-
return 'Medium'
|
|
14
|
-
default:
|
|
15
|
-
return 'Small'
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const getFontKey = (fontFamily: FontFamilyType, fontSize: FontSize): FontKey =>
|
|
20
|
-
`${fontFamily}${getFontKeySize(fontSize)}`
|
|
21
|
-
|
|
22
|
-
export const useFont = (fontFamily: FontFamilyType, fontSize: FontSize) => {
|
|
23
|
-
const { fonts } = useChempoFonts()
|
|
24
|
-
return fonts[getFontKey(fontFamily, fontSize)]
|
|
25
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react'
|
|
2
|
-
import { AppState, Dimensions, PixelRatio, Platform } from 'react-native'
|
|
3
|
-
import { useFontScale } from '../store/useFontScale'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Subscribes to app state and refreshes the global font scale when the app
|
|
7
|
-
* becomes active (cold start or returning from background). Call once near the
|
|
8
|
-
* root of the app (e.g. in _layout).
|
|
9
|
-
*/
|
|
10
|
-
export function useRefreshFontScale(disableFontScaling = false) {
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
if (disableFontScaling) {
|
|
13
|
-
useFontScale.setState({ fontScale: 1 })
|
|
14
|
-
return () => {}
|
|
15
|
-
}
|
|
16
|
-
const refresh = () => useFontScale.setState({ fontScale: PixelRatio.getFontScale() ?? 1 })
|
|
17
|
-
|
|
18
|
-
refresh()
|
|
19
|
-
|
|
20
|
-
const appStateSub = AppState.addEventListener('change', nextState => {
|
|
21
|
-
if (nextState === 'active') refresh()
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// On Android, font scale changes come through Dimensions 'change' events
|
|
25
|
-
// triggered by Android configuration changes. AppState alone is not sufficient
|
|
26
|
-
// because PixelRatio.getFontScale() may not have updated yet when AppState fires.
|
|
27
|
-
const dimensionsSub =
|
|
28
|
-
Platform.OS === 'android'
|
|
29
|
-
? Dimensions.addEventListener('change', ({ window }) => {
|
|
30
|
-
useFontScale.setState({ fontScale: window.fontScale ?? 1 })
|
|
31
|
-
})
|
|
32
|
-
: null
|
|
33
|
-
|
|
34
|
-
return () => {
|
|
35
|
-
appStateSub.remove()
|
|
36
|
-
dimensionsSub?.remove()
|
|
37
|
-
}
|
|
38
|
-
}, [disableFontScaling])
|
|
39
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { ColorMode, Theme } from '@chem-po/core'
|
|
2
|
-
import { ThemeProps } from '@chem-po/react'
|
|
3
|
-
import AsyncStorage from '@react-native-async-storage/async-storage'
|
|
4
|
-
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
5
|
-
|
|
6
|
-
export interface UseThemeProps {
|
|
7
|
-
colorModeProp?: string
|
|
8
|
-
theme?: Theme
|
|
9
|
-
// deprecated - using AsyncStorage instead
|
|
10
|
-
initialColorMode?: ColorMode
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const useThemeState = (props?: UseThemeProps) => {
|
|
14
|
-
const { initialColorMode, theme, colorModeProp = 'chempoColorMode' } = props ?? {}
|
|
15
|
-
const [initialized, setInitialized] = useState(false)
|
|
16
|
-
|
|
17
|
-
const [colorMode, setColorModeState] = useState<ColorMode>(initialColorMode ?? 'light')
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
if (initialized) return
|
|
21
|
-
|
|
22
|
-
const initialize = async () => {
|
|
23
|
-
const storedColorMode = await AsyncStorage.getItem(colorModeProp)
|
|
24
|
-
if (storedColorMode) setColorModeState(storedColorMode as ColorMode)
|
|
25
|
-
else AsyncStorage.setItem(colorModeProp, initialColorMode ?? 'light')
|
|
26
|
-
setInitialized(true)
|
|
27
|
-
}
|
|
28
|
-
initialize()
|
|
29
|
-
}, [initialized, colorModeProp, initialColorMode])
|
|
30
|
-
|
|
31
|
-
const setColorMode = useCallback(
|
|
32
|
-
(colorMode: ColorMode) => {
|
|
33
|
-
setColorModeState(colorMode)
|
|
34
|
-
AsyncStorage.setItem(colorModeProp, colorMode)
|
|
35
|
-
},
|
|
36
|
-
[colorModeProp],
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
return useMemo<ThemeProps>(
|
|
40
|
-
() => ({ colorMode, setColorMode, theme, colorModeProp, initialized }),
|
|
41
|
-
[colorMode, setColorMode, theme, colorModeProp, initialized],
|
|
42
|
-
)
|
|
43
|
-
}
|
package/src/index.ts
DELETED
package/src/store/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { PixelRatio } from 'react-native'
|
|
2
|
-
import { create } from 'zustand'
|
|
3
|
-
|
|
4
|
-
// export const normalizeFontScale = (fontScale: number) =>
|
|
5
|
-
// fontScale > 1 ? (fontScale - 1) * 0.5 + 1 : fontScale
|
|
6
|
-
export const useFontScale = create<{ fontScale: number }>(() => ({
|
|
7
|
-
fontScale: PixelRatio.getFontScale() ?? 1,
|
|
8
|
-
}))
|
package/src/store/useScreen.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { useScreen } from '@chem-po/react'
|
|
2
|
-
import { Dimensions } from 'react-native'
|
|
3
|
-
|
|
4
|
-
export const initializeScreen = () => {
|
|
5
|
-
const onDimensionsChange = () => {
|
|
6
|
-
const { width, height } = Dimensions.get('window')
|
|
7
|
-
useScreen.setState({
|
|
8
|
-
width,
|
|
9
|
-
height,
|
|
10
|
-
isMobile: true, // In React Native, we're always on mobile
|
|
11
|
-
isPortrait: width < height,
|
|
12
|
-
})
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Initial setup
|
|
16
|
-
onDimensionsChange()
|
|
17
|
-
|
|
18
|
-
// Add listener for dimension changes
|
|
19
|
-
const subscription = Dimensions.addEventListener('change', onDimensionsChange)
|
|
20
|
-
|
|
21
|
-
// Return cleanup function
|
|
22
|
-
return () => {
|
|
23
|
-
subscription.remove()
|
|
24
|
-
}
|
|
25
|
-
}
|
package/src/styles/fill.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { StyleProp, StyleSheet, ViewStyle } from 'react-native'
|
|
2
|
-
|
|
3
|
-
const sharedProps: StyleProp<ViewStyle> = {
|
|
4
|
-
top: 0,
|
|
5
|
-
left: 0,
|
|
6
|
-
right: 0,
|
|
7
|
-
bottom: 0,
|
|
8
|
-
display: 'flex',
|
|
9
|
-
}
|
|
10
|
-
export const fill = StyleSheet.create({
|
|
11
|
-
absolute: {
|
|
12
|
-
...sharedProps,
|
|
13
|
-
position: 'absolute',
|
|
14
|
-
},
|
|
15
|
-
relative: {
|
|
16
|
-
...sharedProps,
|
|
17
|
-
position: 'relative',
|
|
18
|
-
},
|
|
19
|
-
})
|
package/src/types/forms.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { BaseCustomInput, BaseCustomInputProps } from '@chem-po/react'
|
|
2
|
-
import { TextStyle, ViewStyle } from 'react-native'
|
|
3
|
-
|
|
4
|
-
export type CustomInput<Value, InputStyle = TextStyle> = BaseCustomInput<
|
|
5
|
-
Value,
|
|
6
|
-
ViewStyle,
|
|
7
|
-
InputStyle
|
|
8
|
-
>
|
|
9
|
-
|
|
10
|
-
export type CustomInputProps<Value, InputStyle = TextStyle> = BaseCustomInputProps<
|
|
11
|
-
Value,
|
|
12
|
-
ViewStyle,
|
|
13
|
-
InputStyle
|
|
14
|
-
>
|
package/src/types/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './forms'
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { Directory, File, Paths } from 'expo-file-system'
|
|
2
|
-
import { StorageAccessFramework } from 'expo-file-system/legacy'
|
|
3
|
-
import { shareAsync } from 'expo-sharing'
|
|
4
|
-
import { Platform } from 'react-native'
|
|
5
|
-
|
|
6
|
-
export const downloadFile = async (uri: string, filename: string, fileType: string) => {
|
|
7
|
-
if (Platform.OS === 'android') {
|
|
8
|
-
const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync()
|
|
9
|
-
if (!permissions.granted) {
|
|
10
|
-
throw new Error('Permission not granted')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Create cache directory for temporary file
|
|
14
|
-
const cacheDir = new Directory(Paths.cache)
|
|
15
|
-
|
|
16
|
-
// Ensure cache directory exists
|
|
17
|
-
if (!cacheDir.exists) {
|
|
18
|
-
cacheDir.create()
|
|
19
|
-
}
|
|
20
|
-
|
|
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)
|
|
30
|
-
|
|
31
|
-
// Create a file within the selected directory using SAF
|
|
32
|
-
const fileUri = await StorageAccessFramework.createFileAsync(
|
|
33
|
-
permissions.directoryUri,
|
|
34
|
-
filename,
|
|
35
|
-
fileType,
|
|
36
|
-
)
|
|
37
|
-
|
|
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',
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
// Clean up temporary file
|
|
44
|
-
downloadedFile.delete()
|
|
45
|
-
|
|
46
|
-
return { uri: fileUri }
|
|
47
|
-
}
|
|
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()
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Download file directly to documents directory
|
|
58
|
-
const downloadedFile = await File.downloadFileAsync(uri, documentsDir)
|
|
59
|
-
|
|
60
|
-
return shareAsync(downloadedFile.uri)
|
|
61
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
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
|
-
}
|