one 1.23.0 → 1.24.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/cjs/headless/__tests__/useStack.test.cjs +79 -0
- package/dist/cjs/headless/__tests__/useStack.test.native.js +85 -0
- package/dist/cjs/headless/__tests__/useStack.test.native.js.map +1 -0
- package/dist/cjs/headless/useStack.cjs +2 -1
- package/dist/cjs/headless/useStack.native.js +2 -1
- package/dist/cjs/headless/useStack.native.js.map +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/layouts/Stack.cjs +12 -9
- package/dist/cjs/layouts/Stack.native.js +13 -10
- package/dist/cjs/layouts/Stack.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackScreen.cjs +6 -3
- package/dist/cjs/layouts/stack-utils/StackScreen.native.js +7 -4
- package/dist/cjs/layouts/stack-utils/StackScreen.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackToolbar.cjs +124 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.native.js +129 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.native.js.map +1 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.shared.cjs +57 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.shared.native.js +61 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.shared.native.js.map +1 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.types.cjs +18 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.types.native.js +21 -0
- package/dist/cjs/layouts/stack-utils/StackToolbar.types.native.js.map +1 -0
- package/dist/cjs/layouts/stack-utils/StackToolbarImplementation.cjs +39 -0
- package/dist/cjs/layouts/stack-utils/StackToolbarImplementation.native.js +41 -0
- package/dist/cjs/layouts/stack-utils/StackToolbarImplementation.native.js.map +1 -0
- package/dist/cjs/layouts/stack-utils/__tests__/StackToolbar.test.cjs +66 -0
- package/dist/cjs/layouts/stack-utils/__tests__/StackToolbar.test.native.js +99 -0
- package/dist/cjs/layouts/stack-utils/__tests__/StackToolbar.test.native.js.map +1 -0
- package/dist/cjs/layouts/stack-utils/index.cjs +2 -0
- package/dist/cjs/layouts/stack-utils/index.native.js +2 -0
- package/dist/cjs/layouts/stack-utils/index.native.js.map +1 -1
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.cjs +9 -3
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.native.js +9 -4
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.native.js.map +1 -1
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.test.cjs +84 -0
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.test.native.js +91 -0
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.test.native.js.map +1 -0
- package/dist/cjs/router/router.native.js.map +1 -1
- package/dist/cjs/router/useInitializeOneRouter.cjs +2 -2
- package/dist/cjs/router/useInitializeOneRouter.native.js +2 -2
- package/dist/cjs/router/useInitializeOneRouter.native.js.map +1 -1
- package/dist/cjs/router/useInitializeOneRouter.preview-lifecycle.test.cjs +1 -1
- package/dist/cjs/router/useInitializeOneRouter.preview-lifecycle.test.native.js +1 -1
- package/dist/cjs/router/useInitializeOneRouter.preview-lifecycle.test.native.js.map +1 -1
- package/dist/cjs/stack-toolbar-implementation.cjs +30 -0
- package/dist/cjs/stack-toolbar-implementation.native.js +33 -0
- package/dist/cjs/stack-toolbar-implementation.native.js.map +1 -0
- package/dist/esm/headless/__tests__/useStack.test.mjs +56 -0
- package/dist/esm/headless/__tests__/useStack.test.mjs.map +1 -0
- package/dist/esm/headless/__tests__/useStack.test.native.js +59 -0
- package/dist/esm/headless/__tests__/useStack.test.native.js.map +1 -0
- package/dist/esm/headless/useStack.mjs +2 -1
- package/dist/esm/headless/useStack.mjs.map +1 -1
- package/dist/esm/headless/useStack.native.js +2 -1
- package/dist/esm/headless/useStack.native.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/layouts/Stack.mjs +13 -10
- package/dist/esm/layouts/Stack.mjs.map +1 -1
- package/dist/esm/layouts/Stack.native.js +14 -11
- package/dist/esm/layouts/Stack.native.js.map +1 -1
- package/dist/esm/layouts/stack-utils/StackScreen.mjs +6 -3
- package/dist/esm/layouts/stack-utils/StackScreen.mjs.map +1 -1
- package/dist/esm/layouts/stack-utils/StackScreen.native.js +7 -4
- package/dist/esm/layouts/stack-utils/StackScreen.native.js.map +1 -1
- package/dist/esm/layouts/stack-utils/StackToolbar.mjs +89 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.mjs.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.native.js +92 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.native.js.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.shared.mjs +31 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.shared.mjs.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.shared.native.js +32 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.shared.native.js.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.types.mjs +2 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.types.mjs.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.types.native.js +2 -0
- package/dist/esm/layouts/stack-utils/StackToolbar.types.native.js.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbarImplementation.mjs +12 -0
- package/dist/esm/layouts/stack-utils/StackToolbarImplementation.mjs.map +1 -0
- package/dist/esm/layouts/stack-utils/StackToolbarImplementation.native.js +12 -0
- package/dist/esm/layouts/stack-utils/StackToolbarImplementation.native.js.map +1 -0
- package/dist/esm/layouts/stack-utils/__tests__/StackToolbar.test.mjs +67 -0
- package/dist/esm/layouts/stack-utils/__tests__/StackToolbar.test.mjs.map +1 -0
- package/dist/esm/layouts/stack-utils/__tests__/StackToolbar.test.native.js +73 -0
- package/dist/esm/layouts/stack-utils/__tests__/StackToolbar.test.native.js.map +1 -0
- package/dist/esm/layouts/stack-utils/index.mjs +2 -1
- package/dist/esm/layouts/stack-utils/index.mjs.map +1 -1
- package/dist/esm/layouts/stack-utils/index.native.js +2 -1
- package/dist/esm/layouts/stack-utils/index.native.js.map +1 -1
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.mjs +9 -3
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.mjs.map +1 -1
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.native.js +9 -4
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.native.js.map +1 -1
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.test.mjs +61 -0
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.test.mjs.map +1 -0
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.test.native.js +65 -0
- package/dist/esm/metro-config/buildOneMetroResolverOverrides.test.native.js.map +1 -0
- package/dist/esm/router/useInitializeOneRouter.mjs +1 -1
- package/dist/esm/router/useInitializeOneRouter.mjs.map +1 -1
- package/dist/esm/router/useInitializeOneRouter.native.js +1 -1
- package/dist/esm/router/useInitializeOneRouter.preview-lifecycle.test.mjs +1 -1
- package/dist/esm/router/useInitializeOneRouter.preview-lifecycle.test.mjs.map +1 -1
- package/dist/esm/router/useInitializeOneRouter.preview-lifecycle.test.native.js +1 -1
- package/dist/esm/router/useInitializeOneRouter.preview-lifecycle.test.native.js.map +1 -1
- package/dist/esm/stack-toolbar-implementation.mjs +3 -0
- package/dist/esm/stack-toolbar-implementation.mjs.map +1 -0
- package/dist/esm/stack-toolbar-implementation.native.js +3 -0
- package/dist/esm/stack-toolbar-implementation.native.js.map +1 -0
- package/package.json +26 -20
- package/src/headless/__tests__/useStack.test.tsx +54 -0
- package/src/headless/types.ts +2 -1
- package/src/headless/useStack.ts +2 -1
- package/src/index.ts +12 -0
- package/src/layouts/Stack.tsx +33 -8
- package/src/layouts/stack-utils/README.md +1 -0
- package/src/layouts/stack-utils/StackScreen.tsx +26 -5
- package/src/layouts/stack-utils/StackToolbar.shared.ts +44 -0
- package/src/layouts/stack-utils/StackToolbar.tsx +134 -0
- package/src/layouts/stack-utils/StackToolbar.types.ts +100 -0
- package/src/layouts/stack-utils/StackToolbarImplementation.tsx +39 -0
- package/src/layouts/stack-utils/__tests__/StackToolbar.test.tsx +70 -0
- package/src/layouts/stack-utils/index.tsx +17 -0
- package/src/metro-config/buildOneMetroResolverOverrides.test.ts +88 -0
- package/src/metro-config/buildOneMetroResolverOverrides.ts +20 -8
- package/src/router/router.ts +5 -5
- package/src/router/useInitializeOneRouter.preview-lifecycle.test.ts +1 -1
- package/src/router/useInitializeOneRouter.ts +2 -2
- package/src/stack-toolbar-implementation.ts +8 -0
- package/types/fork/useLinking.native.d.ts +4 -4
- package/types/headless/types.d.ts +4 -1
- package/types/headless/types.d.ts.map +1 -1
- package/types/headless/useStack.d.ts.map +1 -1
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/layouts/Drawer.d.ts +54 -54
- package/types/layouts/Stack.d.ts +58 -46
- package/types/layouts/Stack.d.ts.map +1 -1
- package/types/layouts/Tabs.d.ts +46 -46
- package/types/layouts/stack-utils/StackScreen.d.ts +2 -1
- package/types/layouts/stack-utils/StackScreen.d.ts.map +1 -1
- package/types/layouts/stack-utils/StackToolbar.d.ts +28 -0
- package/types/layouts/stack-utils/StackToolbar.d.ts.map +1 -0
- package/types/layouts/stack-utils/StackToolbar.shared.d.ts +5 -0
- package/types/layouts/stack-utils/StackToolbar.shared.d.ts.map +1 -0
- package/types/layouts/stack-utils/StackToolbar.types.d.ts +83 -0
- package/types/layouts/stack-utils/StackToolbar.types.d.ts.map +1 -0
- package/types/layouts/stack-utils/StackToolbarImplementation.d.ts +12 -0
- package/types/layouts/stack-utils/StackToolbarImplementation.d.ts.map +1 -0
- package/types/layouts/stack-utils/index.d.ts +3 -1
- package/types/layouts/stack-utils/index.d.ts.map +1 -1
- package/types/metro-config/buildOneMetroResolverOverrides.d.ts +2 -1
- package/types/metro-config/buildOneMetroResolverOverrides.d.ts.map +1 -1
- package/types/metro-config/buildOneMetroResolverOverrides.test.d.ts +2 -0
- package/types/metro-config/buildOneMetroResolverOverrides.test.d.ts.map +1 -0
- package/types/router/router.d.ts +1 -1
- package/types/router/router.d.ts.map +1 -1
- package/types/stack-toolbar-implementation.d.ts +3 -0
- package/types/stack-toolbar-implementation.d.ts.map +1 -0
- package/types/ui/TabContext.d.ts +15 -23
- package/types/ui/TabContext.d.ts.map +1 -1
- package/types/ui/TabRouter.d.ts +5 -5
- package/types/ui/Tabs.shared.d.ts +22 -22
- package/types/ui/Tabs.shared.d.ts.map +1 -1
package/src/layouts/Stack.tsx
CHANGED
|
@@ -14,9 +14,14 @@ import {
|
|
|
14
14
|
StackHeaderComponent,
|
|
15
15
|
StackHeaderSearchBar,
|
|
16
16
|
StackScreen,
|
|
17
|
+
StackToolbar,
|
|
17
18
|
type StackScreenProps,
|
|
18
19
|
} from './stack-utils'
|
|
19
20
|
import { withLayoutContext } from './withLayoutContext'
|
|
21
|
+
import {
|
|
22
|
+
getStackToolbarImplementation,
|
|
23
|
+
type StackToolbarImplementation,
|
|
24
|
+
} from './stack-utils/StackToolbarImplementation'
|
|
20
25
|
|
|
21
26
|
const NativeStackNavigator = createStackNavigator().Navigator
|
|
22
27
|
|
|
@@ -31,12 +36,19 @@ const RNStack = withLayoutContext<
|
|
|
31
36
|
* Pre-process children to convert StackScreen (with Header children) to Screen (with options).
|
|
32
37
|
* This allows the Header Composition API to work in layout files.
|
|
33
38
|
*/
|
|
34
|
-
function mapChildren(
|
|
39
|
+
function mapChildren(
|
|
40
|
+
children: React.ReactNode,
|
|
41
|
+
toolbarImplementation: StackToolbarImplementation | null
|
|
42
|
+
): React.ReactNode {
|
|
35
43
|
return Children.toArray(children)
|
|
36
44
|
.map((child, index) => {
|
|
37
45
|
if (isChildOfType(child, StackScreen)) {
|
|
38
46
|
// convert StackScreen to Screen with options extracted from Header children
|
|
39
|
-
const options = appendScreenStackPropsToOptions(
|
|
47
|
+
const options = appendScreenStackPropsToOptions(
|
|
48
|
+
{},
|
|
49
|
+
child.props,
|
|
50
|
+
toolbarImplementation
|
|
51
|
+
)
|
|
40
52
|
const { children: _, ...rest } = child.props
|
|
41
53
|
return <Screen key={child.props.name ?? index} {...rest} options={options} />
|
|
42
54
|
}
|
|
@@ -46,7 +58,7 @@ function mapChildren(children: React.ReactNode): React.ReactNode {
|
|
|
46
58
|
return React.cloneElement(
|
|
47
59
|
child,
|
|
48
60
|
{ key: `protected-${index}` },
|
|
49
|
-
mapChildren(child.props.children)
|
|
61
|
+
mapChildren(child.props.children, toolbarImplementation)
|
|
50
62
|
)
|
|
51
63
|
}
|
|
52
64
|
|
|
@@ -71,6 +83,7 @@ function mapChildren(children: React.ReactNode): React.ReactNode {
|
|
|
71
83
|
const StackWithComposition = React.forwardRef<unknown, ComponentProps<typeof RNStack>>(
|
|
72
84
|
(props, ref) => {
|
|
73
85
|
const { children, screenOptions, ...rest } = props
|
|
86
|
+
const toolbarImplementation = getStackToolbarImplementation()
|
|
74
87
|
|
|
75
88
|
// extract Stack.Header from children for screenOptions
|
|
76
89
|
const screenOptionsWithHeader = useMemo(() => {
|
|
@@ -84,19 +97,30 @@ const StackWithComposition = React.forwardRef<unknown, ComponentProps<typeof RNS
|
|
|
84
97
|
if (typeof screenOptions === 'function') {
|
|
85
98
|
return (...args: Parameters<typeof screenOptions>) => {
|
|
86
99
|
const opts = screenOptions(...args)
|
|
87
|
-
return appendScreenStackPropsToOptions(
|
|
100
|
+
return appendScreenStackPropsToOptions(
|
|
101
|
+
opts,
|
|
102
|
+
headerProps,
|
|
103
|
+
toolbarImplementation
|
|
104
|
+
)
|
|
88
105
|
}
|
|
89
106
|
}
|
|
90
|
-
return appendScreenStackPropsToOptions(
|
|
107
|
+
return appendScreenStackPropsToOptions(
|
|
108
|
+
screenOptions,
|
|
109
|
+
headerProps,
|
|
110
|
+
toolbarImplementation
|
|
111
|
+
)
|
|
91
112
|
}
|
|
92
|
-
return appendScreenStackPropsToOptions({}, headerProps)
|
|
113
|
+
return appendScreenStackPropsToOptions({}, headerProps, toolbarImplementation)
|
|
93
114
|
}
|
|
94
115
|
|
|
95
116
|
return screenOptions
|
|
96
|
-
}, [children, screenOptions])
|
|
117
|
+
}, [children, screenOptions, toolbarImplementation])
|
|
97
118
|
|
|
98
119
|
// pre-process children to convert StackScreen to Screen
|
|
99
|
-
const processedChildren = useMemo(
|
|
120
|
+
const processedChildren = useMemo(
|
|
121
|
+
() => mapChildren(children, toolbarImplementation),
|
|
122
|
+
[children, toolbarImplementation]
|
|
123
|
+
)
|
|
100
124
|
const navigatorProps = useMemo(() => getStackNavigatorProps(children), [children])
|
|
101
125
|
|
|
102
126
|
return (
|
|
@@ -119,6 +143,7 @@ export const Stack = Object.assign(StackWithComposition, {
|
|
|
119
143
|
Header: StackHeader,
|
|
120
144
|
Protected,
|
|
121
145
|
SearchBar: StackHeaderSearchBar,
|
|
146
|
+
Toolbar: StackToolbar,
|
|
122
147
|
})
|
|
123
148
|
|
|
124
149
|
export default Stack
|
|
@@ -25,6 +25,7 @@ import { Stack } from 'one'
|
|
|
25
25
|
| `Stack.Header.Right` | Custom right header content |
|
|
26
26
|
| `Stack.Header.BackButton` | Back button configuration |
|
|
27
27
|
| `Stack.Header.SearchBar` | Search bar configuration |
|
|
28
|
+
| `Stack.Toolbar` | Native iOS header and bottom toolbar items |
|
|
28
29
|
|
|
29
30
|
## Basic Usage
|
|
30
31
|
|
|
@@ -9,6 +9,15 @@ import {
|
|
|
9
9
|
appendStackHeaderPropsToOptions,
|
|
10
10
|
type StackHeaderProps,
|
|
11
11
|
} from './StackHeaderComponent'
|
|
12
|
+
import {
|
|
13
|
+
StackToolbar,
|
|
14
|
+
appendStackToolbarPropsToOptions,
|
|
15
|
+
type StackToolbarProps,
|
|
16
|
+
} from './StackToolbar'
|
|
17
|
+
import {
|
|
18
|
+
getStackToolbarImplementation,
|
|
19
|
+
type StackToolbarImplementation,
|
|
20
|
+
} from './StackToolbarImplementation'
|
|
12
21
|
import { Screen } from '../../views/Screen'
|
|
13
22
|
|
|
14
23
|
export type StackScreenOptions = Omit<NativeStackNavigationOptions, 'presentation'> & {
|
|
@@ -47,12 +56,17 @@ export interface StackScreenProps extends PropsWithChildren {
|
|
|
47
56
|
* ```
|
|
48
57
|
*/
|
|
49
58
|
export function StackScreen({ children, options, ...rest }: StackScreenProps) {
|
|
59
|
+
const toolbarImplementation = getStackToolbarImplementation()
|
|
50
60
|
const updatedOptions = useMemo(
|
|
51
61
|
() =>
|
|
52
|
-
appendScreenStackPropsToOptions(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
appendScreenStackPropsToOptions(
|
|
63
|
+
options ?? {},
|
|
64
|
+
{
|
|
65
|
+
children,
|
|
66
|
+
},
|
|
67
|
+
toolbarImplementation
|
|
68
|
+
),
|
|
69
|
+
[options, children, toolbarImplementation]
|
|
56
70
|
)
|
|
57
71
|
return <Screen {...rest} options={updatedOptions as NativeStackNavigationOptions} />
|
|
58
72
|
}
|
|
@@ -101,7 +115,8 @@ export function validateStackPresentation(
|
|
|
101
115
|
|
|
102
116
|
export function appendScreenStackPropsToOptions(
|
|
103
117
|
options: StackScreenOptions,
|
|
104
|
-
props: StackScreenProps
|
|
118
|
+
props: StackScreenProps,
|
|
119
|
+
toolbarImplementation?: StackToolbarImplementation | null
|
|
105
120
|
): StackScreenOptions {
|
|
106
121
|
let updatedOptions: StackScreenOptions = { ...options, ...props.options }
|
|
107
122
|
|
|
@@ -114,6 +129,12 @@ export function appendScreenStackPropsToOptions(
|
|
|
114
129
|
options as NativeStackNavigationOptions,
|
|
115
130
|
child.props as StackHeaderProps
|
|
116
131
|
) as StackScreenOptions
|
|
132
|
+
} else if (child.type === StackToolbar) {
|
|
133
|
+
return appendStackToolbarPropsToOptions(
|
|
134
|
+
options as NativeStackNavigationOptions,
|
|
135
|
+
child.props as StackToolbarProps,
|
|
136
|
+
toolbarImplementation
|
|
137
|
+
) as StackScreenOptions
|
|
117
138
|
} else {
|
|
118
139
|
console.warn(
|
|
119
140
|
`Warning: Unknown child element passed to Stack.Screen: ${(child.type as { name: string }).name ?? child.type}`
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
StackToolbarConfig,
|
|
5
|
+
StackToolbarPlacement,
|
|
6
|
+
StackToolbarProps,
|
|
7
|
+
} from './StackToolbar.types'
|
|
8
|
+
|
|
9
|
+
const optionKeys = {
|
|
10
|
+
left: '__oneStackToolbarLeft',
|
|
11
|
+
right: '__oneStackToolbarRight',
|
|
12
|
+
bottom: '__oneStackToolbarBottom',
|
|
13
|
+
} as const satisfies Record<StackToolbarPlacement, string>
|
|
14
|
+
|
|
15
|
+
export function appendStackToolbarConfig(
|
|
16
|
+
options: NativeStackNavigationOptions,
|
|
17
|
+
props: StackToolbarProps
|
|
18
|
+
): NativeStackNavigationOptions {
|
|
19
|
+
return {
|
|
20
|
+
...options,
|
|
21
|
+
[optionKeys[props.placement ?? 'bottom']]: props,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function exposeStackToolbarConfig(
|
|
26
|
+
options: Record<string, any>
|
|
27
|
+
): Record<string, any> {
|
|
28
|
+
const toolbar: StackToolbarConfig = {
|
|
29
|
+
left: options[optionKeys.left],
|
|
30
|
+
right: options[optionKeys.right],
|
|
31
|
+
bottom: options[optionKeys.bottom],
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!toolbar.left && !toolbar.right && !toolbar.bottom) return options
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
[optionKeys.left]: _left,
|
|
38
|
+
[optionKeys.right]: _right,
|
|
39
|
+
[optionKeys.bottom]: _bottom,
|
|
40
|
+
...publicOptions
|
|
41
|
+
} = options
|
|
42
|
+
|
|
43
|
+
return { ...publicOptions, toolbar }
|
|
44
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
|
4
|
+
import { useMemo } from 'react'
|
|
5
|
+
|
|
6
|
+
import { useIsomorphicLayoutEffect } from '@vxrn/use-isomorphic-layout-effect'
|
|
7
|
+
import { NAVIGATOR_CONFIG } from '../../headless/children'
|
|
8
|
+
import { useNavigation } from '../../router/useNavigation'
|
|
9
|
+
import {
|
|
10
|
+
STACK_TOOLBAR_CHILD,
|
|
11
|
+
getStackToolbarImplementation,
|
|
12
|
+
type StackToolbarImplementation,
|
|
13
|
+
} from './StackToolbarImplementation'
|
|
14
|
+
import { appendStackToolbarConfig } from './StackToolbar.shared'
|
|
15
|
+
import type {
|
|
16
|
+
StackToolbarBadgeProps,
|
|
17
|
+
StackToolbarButtonProps,
|
|
18
|
+
StackToolbarIconProps,
|
|
19
|
+
StackToolbarLabelProps,
|
|
20
|
+
StackToolbarMenuActionProps,
|
|
21
|
+
StackToolbarMenuProps,
|
|
22
|
+
StackToolbarProps,
|
|
23
|
+
StackToolbarSearchBarSlotProps,
|
|
24
|
+
StackToolbarSpacerProps,
|
|
25
|
+
StackToolbarViewProps,
|
|
26
|
+
} from './StackToolbar.types'
|
|
27
|
+
|
|
28
|
+
export function appendStackToolbarPropsToOptions(
|
|
29
|
+
options: NativeStackNavigationOptions,
|
|
30
|
+
props: StackToolbarProps,
|
|
31
|
+
implementation?: StackToolbarImplementation | null
|
|
32
|
+
) {
|
|
33
|
+
const optionsWithConfig = appendStackToolbarConfig(options, props)
|
|
34
|
+
return implementation
|
|
35
|
+
? implementation.appendPropsToOptions(optionsWithConfig, props)
|
|
36
|
+
: optionsWithConfig
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function StackToolbarComponent(props: StackToolbarProps) {
|
|
40
|
+
const navigation = useNavigation()
|
|
41
|
+
const implementation = getStackToolbarImplementation()
|
|
42
|
+
const options = useMemo(
|
|
43
|
+
() => appendStackToolbarPropsToOptions({}, props, implementation),
|
|
44
|
+
[
|
|
45
|
+
implementation,
|
|
46
|
+
props.placement,
|
|
47
|
+
props.asChild,
|
|
48
|
+
props.children,
|
|
49
|
+
props.disableImePadding,
|
|
50
|
+
props.tintColor,
|
|
51
|
+
props.backgroundColor,
|
|
52
|
+
]
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
useIsomorphicLayoutEffect(() => {
|
|
56
|
+
navigation.setOptions(options)
|
|
57
|
+
}, [navigation, options])
|
|
58
|
+
|
|
59
|
+
return implementation?.render(props) ?? null
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function StackToolbarButton(_props: StackToolbarButtonProps) {
|
|
63
|
+
return null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function StackToolbarMenu(_props: StackToolbarMenuProps) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function StackToolbarMenuAction(_props: StackToolbarMenuActionProps) {
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function StackToolbarSpacer(_props: StackToolbarSpacerProps) {
|
|
75
|
+
return null
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function StackToolbarSearchBarSlot(_props: StackToolbarSearchBarSlotProps) {
|
|
79
|
+
return null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function StackToolbarView(_props: StackToolbarViewProps) {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function StackToolbarLabel(_props: StackToolbarLabelProps) {
|
|
87
|
+
return null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function StackToolbarIcon(_props: StackToolbarIconProps) {
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function StackToolbarBadge(_props: StackToolbarBadgeProps) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Object.assign(StackToolbarButton, { [STACK_TOOLBAR_CHILD]: 'button' })
|
|
99
|
+
Object.assign(StackToolbarMenu, { [STACK_TOOLBAR_CHILD]: 'menu' })
|
|
100
|
+
Object.assign(StackToolbarMenuAction, { [STACK_TOOLBAR_CHILD]: 'menuAction' })
|
|
101
|
+
Object.assign(StackToolbarSpacer, { [STACK_TOOLBAR_CHILD]: 'spacer' })
|
|
102
|
+
Object.assign(StackToolbarSearchBarSlot, { [STACK_TOOLBAR_CHILD]: 'searchBarSlot' })
|
|
103
|
+
Object.assign(StackToolbarView, { [STACK_TOOLBAR_CHILD]: 'view' })
|
|
104
|
+
Object.assign(StackToolbarLabel, { [STACK_TOOLBAR_CHILD]: 'label' })
|
|
105
|
+
Object.assign(StackToolbarIcon, { [STACK_TOOLBAR_CHILD]: 'icon' })
|
|
106
|
+
Object.assign(StackToolbarBadge, { [STACK_TOOLBAR_CHILD]: 'badge' })
|
|
107
|
+
|
|
108
|
+
export const StackToolbar = Object.assign(StackToolbarComponent, {
|
|
109
|
+
[NAVIGATOR_CONFIG]: true,
|
|
110
|
+
Button: StackToolbarButton,
|
|
111
|
+
Menu: StackToolbarMenu,
|
|
112
|
+
MenuAction: StackToolbarMenuAction,
|
|
113
|
+
Spacer: StackToolbarSpacer,
|
|
114
|
+
SearchBarSlot: StackToolbarSearchBarSlot,
|
|
115
|
+
View: StackToolbarView,
|
|
116
|
+
Label: StackToolbarLabel,
|
|
117
|
+
Icon: StackToolbarIcon,
|
|
118
|
+
Badge: StackToolbarBadge,
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
export type {
|
|
122
|
+
StackToolbarBadgeProps,
|
|
123
|
+
StackToolbarButtonProps,
|
|
124
|
+
StackToolbarConfig,
|
|
125
|
+
StackToolbarIconProps,
|
|
126
|
+
StackToolbarLabelProps,
|
|
127
|
+
StackToolbarMenuActionProps,
|
|
128
|
+
StackToolbarMenuProps,
|
|
129
|
+
StackToolbarPlacement,
|
|
130
|
+
StackToolbarProps,
|
|
131
|
+
StackToolbarSearchBarSlotProps,
|
|
132
|
+
StackToolbarSpacerProps,
|
|
133
|
+
StackToolbarViewProps,
|
|
134
|
+
} from './StackToolbar.types'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native'
|
|
3
|
+
|
|
4
|
+
export type StackToolbarPlacement = 'left' | 'right' | 'bottom'
|
|
5
|
+
|
|
6
|
+
export interface StackToolbarProps {
|
|
7
|
+
children?: ReactNode
|
|
8
|
+
placement?: StackToolbarPlacement
|
|
9
|
+
asChild?: boolean
|
|
10
|
+
/** Android-only. The Android toolbar host is not implemented yet. */
|
|
11
|
+
disableImePadding?: boolean
|
|
12
|
+
/** Android-only. The Android toolbar host is not implemented yet. */
|
|
13
|
+
tintColor?: ColorValue
|
|
14
|
+
/** Android-only. The Android toolbar host is not implemented yet. */
|
|
15
|
+
backgroundColor?: ColorValue
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type StackToolbarConfig = Partial<Record<StackToolbarPlacement, StackToolbarProps>>
|
|
19
|
+
|
|
20
|
+
export interface StackToolbarIconProps {
|
|
21
|
+
src?: ImageSourcePropType
|
|
22
|
+
sf?: string
|
|
23
|
+
xcasset?: string
|
|
24
|
+
renderingMode?: 'template' | 'original'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface StackToolbarLabelProps {
|
|
28
|
+
children?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface StackToolbarBadgeProps {
|
|
32
|
+
children?: string
|
|
33
|
+
style?: StyleProp<
|
|
34
|
+
Pick<
|
|
35
|
+
TextStyle,
|
|
36
|
+
'fontFamily' | 'fontSize' | 'fontWeight' | 'color' | 'backgroundColor'
|
|
37
|
+
>
|
|
38
|
+
>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface StackToolbarItemProps {
|
|
42
|
+
children?: ReactNode
|
|
43
|
+
icon?: string | ImageSourcePropType
|
|
44
|
+
iconRenderingMode?: 'template' | 'original'
|
|
45
|
+
tintColor?: ColorValue
|
|
46
|
+
hidden?: boolean
|
|
47
|
+
disabled?: boolean
|
|
48
|
+
accessibilityLabel?: string
|
|
49
|
+
accessibilityHint?: string
|
|
50
|
+
hidesSharedBackground?: boolean
|
|
51
|
+
separateBackground?: boolean
|
|
52
|
+
style?: StyleProp<TextStyle>
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface StackToolbarButtonProps extends StackToolbarItemProps {
|
|
56
|
+
image?: ImageSourcePropType
|
|
57
|
+
onPress?: () => void
|
|
58
|
+
selected?: boolean
|
|
59
|
+
variant?: 'plain' | 'done' | 'prominent'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface StackToolbarMenuProps extends StackToolbarItemProps {
|
|
63
|
+
image?: ImageSourcePropType
|
|
64
|
+
destructive?: boolean
|
|
65
|
+
title?: string
|
|
66
|
+
inline?: boolean
|
|
67
|
+
palette?: boolean
|
|
68
|
+
singleSelection?: boolean
|
|
69
|
+
elementSize?: 'auto' | 'small' | 'medium' | 'large'
|
|
70
|
+
variant?: 'plain' | 'done' | 'prominent'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface StackToolbarMenuActionProps extends StackToolbarItemProps {
|
|
74
|
+
image?: ImageSourcePropType
|
|
75
|
+
destructive?: boolean
|
|
76
|
+
discoverabilityLabel?: string
|
|
77
|
+
subtitle?: string
|
|
78
|
+
isOn?: boolean
|
|
79
|
+
onPress?: () => void
|
|
80
|
+
unstable_keepPresented?: boolean
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface StackToolbarSpacerProps {
|
|
84
|
+
width?: number
|
|
85
|
+
hidden?: boolean
|
|
86
|
+
sharesBackground?: boolean
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface StackToolbarSearchBarSlotProps {
|
|
90
|
+
hidden?: boolean
|
|
91
|
+
hidesSharedBackground?: boolean
|
|
92
|
+
separateBackground?: boolean
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface StackToolbarViewProps {
|
|
96
|
+
children?: ReactNode
|
|
97
|
+
hidden?: boolean
|
|
98
|
+
hidesSharedBackground?: boolean
|
|
99
|
+
separateBackground?: boolean
|
|
100
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
|
4
|
+
import type { ReactNode } from 'react'
|
|
5
|
+
|
|
6
|
+
import type { StackToolbarProps } from './StackToolbar.types'
|
|
7
|
+
|
|
8
|
+
export const STACK_TOOLBAR_CHILD = Symbol.for('one.stack-toolbar.child')
|
|
9
|
+
|
|
10
|
+
export type StackToolbarChildType =
|
|
11
|
+
| 'button'
|
|
12
|
+
| 'menu'
|
|
13
|
+
| 'menuAction'
|
|
14
|
+
| 'spacer'
|
|
15
|
+
| 'searchBarSlot'
|
|
16
|
+
| 'view'
|
|
17
|
+
| 'label'
|
|
18
|
+
| 'icon'
|
|
19
|
+
| 'badge'
|
|
20
|
+
|
|
21
|
+
export type StackToolbarImplementation = {
|
|
22
|
+
appendPropsToOptions: (
|
|
23
|
+
options: NativeStackNavigationOptions,
|
|
24
|
+
props: StackToolbarProps
|
|
25
|
+
) => NativeStackNavigationOptions
|
|
26
|
+
render: (props: StackToolbarProps) => ReactNode
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let stackToolbarImplementation: StackToolbarImplementation | null = null
|
|
30
|
+
|
|
31
|
+
export function registerStackToolbarImplementation(
|
|
32
|
+
implementation: StackToolbarImplementation
|
|
33
|
+
) {
|
|
34
|
+
stackToolbarImplementation = implementation
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function getStackToolbarImplementation() {
|
|
38
|
+
return stackToolbarImplementation
|
|
39
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
3
|
+
import type { StackToolbarImplementation } from '../StackToolbarImplementation'
|
|
4
|
+
|
|
5
|
+
import { StackToolbar } from '../StackToolbar'
|
|
6
|
+
import { STACK_TOOLBAR_CHILD } from '../StackToolbarImplementation'
|
|
7
|
+
import { exposeStackToolbarConfig } from '../StackToolbar.shared'
|
|
8
|
+
import { appendScreenStackPropsToOptions } from '../StackScreen'
|
|
9
|
+
|
|
10
|
+
describe('Stack.Toolbar headless config', () => {
|
|
11
|
+
it('marks declaration children for installed implementations', () => {
|
|
12
|
+
expect(
|
|
13
|
+
(StackToolbar.Button as unknown as Record<symbol, string>)[STACK_TOOLBAR_CHILD]
|
|
14
|
+
).toBe('button')
|
|
15
|
+
expect(
|
|
16
|
+
(StackToolbar.MenuAction as unknown as Record<symbol, string>)[STACK_TOOLBAR_CHILD]
|
|
17
|
+
).toBe('menuAction')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('preserves every placement for the headless stack implementation', () => {
|
|
21
|
+
const options = appendScreenStackPropsToOptions(
|
|
22
|
+
{ title: 'Inbox' },
|
|
23
|
+
{
|
|
24
|
+
children: [
|
|
25
|
+
<StackToolbar key="left" placement="left">
|
|
26
|
+
<StackToolbar.Button icon="sidebar.left" />
|
|
27
|
+
</StackToolbar>,
|
|
28
|
+
<StackToolbar key="right" placement="right">
|
|
29
|
+
<StackToolbar.Button icon="square.and.arrow.up" />
|
|
30
|
+
</StackToolbar>,
|
|
31
|
+
],
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
expect(exposeStackToolbarConfig(options)).toMatchObject({
|
|
36
|
+
title: 'Inbox',
|
|
37
|
+
toolbar: {
|
|
38
|
+
left: { placement: 'left' },
|
|
39
|
+
right: { placement: 'right' },
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('hands toolbar declarations to an installed implementation', () => {
|
|
45
|
+
const appendPropsToOptions = vi.fn((options) => ({
|
|
46
|
+
...options,
|
|
47
|
+
headerShown: true,
|
|
48
|
+
}))
|
|
49
|
+
const implementation: StackToolbarImplementation = {
|
|
50
|
+
appendPropsToOptions,
|
|
51
|
+
render: () => null,
|
|
52
|
+
}
|
|
53
|
+
const toolbar = (
|
|
54
|
+
<StackToolbar placement="right">
|
|
55
|
+
<StackToolbar.Button icon="square.and.arrow.up">Share</StackToolbar.Button>
|
|
56
|
+
</StackToolbar>
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const options = appendScreenStackPropsToOptions(
|
|
60
|
+
{ title: 'Inbox' },
|
|
61
|
+
{ children: toolbar },
|
|
62
|
+
implementation
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
expect(options.headerShown).toBe(true)
|
|
66
|
+
expect(appendPropsToOptions).toHaveBeenCalledOnce()
|
|
67
|
+
expect(appendPropsToOptions.mock.calls[0]?.[1]).toBe(toolbar.props)
|
|
68
|
+
expect(exposeStackToolbarConfig(options).toolbar.right).toBe(toolbar.props)
|
|
69
|
+
})
|
|
70
|
+
})
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type StackHeaderSearchBarProps,
|
|
11
11
|
} from './StackHeaderSearchBar'
|
|
12
12
|
import { StackHeaderTitle, type StackHeaderTitleProps } from './StackHeaderTitle'
|
|
13
|
+
import { StackToolbar } from './StackToolbar'
|
|
13
14
|
import { NAVIGATOR_CONFIG } from '../../headless/children'
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -38,8 +39,24 @@ export {
|
|
|
38
39
|
type StackHeaderSearchBarProps,
|
|
39
40
|
StackHeaderTitle,
|
|
40
41
|
type StackHeaderTitleProps,
|
|
42
|
+
StackToolbar,
|
|
41
43
|
}
|
|
42
44
|
|
|
45
|
+
export type {
|
|
46
|
+
StackToolbarBadgeProps,
|
|
47
|
+
StackToolbarButtonProps,
|
|
48
|
+
StackToolbarConfig,
|
|
49
|
+
StackToolbarIconProps,
|
|
50
|
+
StackToolbarLabelProps,
|
|
51
|
+
StackToolbarMenuActionProps,
|
|
52
|
+
StackToolbarMenuProps,
|
|
53
|
+
StackToolbarPlacement,
|
|
54
|
+
StackToolbarProps,
|
|
55
|
+
StackToolbarSearchBarSlotProps,
|
|
56
|
+
StackToolbarSpacerProps,
|
|
57
|
+
StackToolbarViewProps,
|
|
58
|
+
} from './StackToolbar'
|
|
59
|
+
|
|
43
60
|
export {
|
|
44
61
|
StackScreen,
|
|
45
62
|
appendScreenStackPropsToOptions,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { describe, expect, it } from 'vitest'
|
|
3
|
+
import { buildOneMetroResolverOverrides } from './buildOneMetroResolverOverrides'
|
|
4
|
+
|
|
5
|
+
describe('buildOneMetroResolverOverrides', () => {
|
|
6
|
+
it('resolves every react-native-worklets import from the app root', () => {
|
|
7
|
+
const projectRoot = path.resolve(__dirname, '../../')
|
|
8
|
+
const nestedOrigin = path.join(
|
|
9
|
+
projectRoot,
|
|
10
|
+
'node_modules/react-native-reanimated/src/index.ts'
|
|
11
|
+
)
|
|
12
|
+
const resolvedOrigins: string[] = []
|
|
13
|
+
const config = buildOneMetroResolverOverrides({ projectRoot })({
|
|
14
|
+
resolver: {
|
|
15
|
+
resolveRequest: (
|
|
16
|
+
context: { originModulePath: string },
|
|
17
|
+
moduleName: string,
|
|
18
|
+
_platform: string
|
|
19
|
+
) => {
|
|
20
|
+
resolvedOrigins.push(`${moduleName}:${context.originModulePath}`)
|
|
21
|
+
return { type: 'sourceFile', filePath: moduleName }
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
const resolveRequest = config.resolver?.resolveRequest
|
|
26
|
+
|
|
27
|
+
if (!resolveRequest) {
|
|
28
|
+
throw new Error('expected a Metro resolver override')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
resolveRequest({ originModulePath: nestedOrigin }, 'react-native-worklets', 'ios')
|
|
32
|
+
resolveRequest(
|
|
33
|
+
{ originModulePath: nestedOrigin },
|
|
34
|
+
'react-native-worklets/package.json',
|
|
35
|
+
'ios'
|
|
36
|
+
)
|
|
37
|
+
resolveRequest(
|
|
38
|
+
{ originModulePath: nestedOrigin },
|
|
39
|
+
'react-native-safe-area-context',
|
|
40
|
+
'ios'
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
expect(resolvedOrigins).toEqual([
|
|
44
|
+
`react-native-worklets:${path.join(projectRoot, 'package.json')}`,
|
|
45
|
+
`react-native-worklets/package.json:${path.join(projectRoot, 'package.json')}`,
|
|
46
|
+
`react-native-safe-area-context:${nestedOrigin}`,
|
|
47
|
+
])
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('keeps the compiled react-native-svg native entry point', () => {
|
|
51
|
+
const projectRoot = path.resolve(__dirname, '../../')
|
|
52
|
+
const config = buildOneMetroResolverOverrides({ projectRoot })({
|
|
53
|
+
resolver: {
|
|
54
|
+
resolveRequest: (
|
|
55
|
+
_context: { originModulePath: string },
|
|
56
|
+
moduleName: string,
|
|
57
|
+
_platform: string
|
|
58
|
+
) => ({
|
|
59
|
+
type: 'sourceFile',
|
|
60
|
+
filePath: path.join(projectRoot, 'node_modules', moduleName, 'src', 'index.ts'),
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
})
|
|
64
|
+
const resolveRequest = config.resolver?.resolveRequest
|
|
65
|
+
|
|
66
|
+
if (!resolveRequest) {
|
|
67
|
+
throw new Error('expected a Metro resolver override')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
expect(
|
|
71
|
+
resolveRequest(
|
|
72
|
+
{ originModulePath: path.join(projectRoot, 'app.tsx') },
|
|
73
|
+
'react-native-svg',
|
|
74
|
+
'ios'
|
|
75
|
+
)
|
|
76
|
+
).toEqual({
|
|
77
|
+
type: 'sourceFile',
|
|
78
|
+
filePath: path.join(
|
|
79
|
+
projectRoot,
|
|
80
|
+
'node_modules',
|
|
81
|
+
'react-native-svg',
|
|
82
|
+
'lib',
|
|
83
|
+
'commonjs',
|
|
84
|
+
'index.js'
|
|
85
|
+
),
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
})
|