react-native-auto-positioned-popup 1.0.2

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.
@@ -0,0 +1,306 @@
1
+ import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react';
2
+ import { Dimensions, Keyboard, Text, TextInput as RNTextInput, TouchableOpacity, View, } from 'react-native';
3
+ import { AdvancedFlatList } from 'react-native-advanced-flatlist';
4
+ import styles from './AutoPositionedPopup.style';
5
+ import { useRootView } from './RootViewContext';
6
+ const queryChangeListeners = [];
7
+ const emitQueryChange = (query) => {
8
+ console.log('AutoPositionedPopup.tsx emitQueryChange query=', query, ' listeners=', queryChangeListeners.length);
9
+ queryChangeListeners.forEach((l) => l(query));
10
+ };
11
+ const subscribeQueryChange = (listener) => {
12
+ queryChangeListeners.push(listener);
13
+ return () => {
14
+ const idx = queryChangeListeners.indexOf(listener);
15
+ if (idx !== -1)
16
+ queryChangeListeners.splice(idx, 1);
17
+ };
18
+ };
19
+ // Default light theme
20
+ const defaultTheme = {
21
+ colors: {
22
+ text: '#333333',
23
+ placeholderText: '#999999',
24
+ background: '#FFFFFF',
25
+ border: '#E0E0E0',
26
+ },
27
+ };
28
+ // List item component for rendering individual items
29
+ const ListItem = memo(({ item, index, selectedItem, onItemPress, theme, rootViewsRef, selectedItemBackgroundColor = 'rgba(116, 116, 128, 0.08)' }) => {
30
+ const isSelected = item.id === (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id);
31
+ return useMemo(() => (<TouchableOpacity key={item.id} style={[
32
+ styles.commonModalRow,
33
+ {
34
+ backgroundColor: isSelected ? selectedItemBackgroundColor : 'transparent',
35
+ borderColor: theme.colors.border,
36
+ },
37
+ ]} onPress={() => {
38
+ console.log('AutoPositionedPopup.tsx ListItem onPress item=', item);
39
+ if (rootViewsRef) {
40
+ console.log('AutoPositionedPopup.tsx ListItem onPress rootViews=', rootViewsRef.current);
41
+ }
42
+ onItemPress(item);
43
+ }}>
44
+ <Text style={[styles.ListItemCode, { color: theme.colors.text }]} numberOfLines={1} ellipsizeMode="tail">
45
+ {item.title}
46
+ </Text>
47
+ </TouchableOpacity>), [item, index, selectedItem, onItemPress, theme, rootViewsRef, isSelected, selectedItemBackgroundColor]);
48
+ });
49
+ const PopupList = memo(({ data, selectedItem, onItemPress, renderItem, keyExtractor = (item) => String(item.id), theme, rootViewsRef, fetchData, localSearch = false, pageSize = 20, onDataUpdate, selectedItemBackgroundColor, }) => {
50
+ const [internalData, setInternalData] = useState(data);
51
+ const searchQueryRef = useRef('');
52
+ // Sync external data changes
53
+ useEffect(() => {
54
+ setInternalData(data);
55
+ }, [data]);
56
+ // Listen to search query changes
57
+ useEffect(() => {
58
+ const unsubscribe = subscribeQueryChange(async (newQuery) => {
59
+ console.log('PopupList subscribeQueryChange newQuery=', newQuery);
60
+ searchQueryRef.current = newQuery;
61
+ if (fetchData) {
62
+ try {
63
+ const result = await fetchData({
64
+ pageIndex: 0,
65
+ pageSize,
66
+ searchQuery: newQuery,
67
+ });
68
+ if (result === null || result === void 0 ? void 0 : result.items) {
69
+ setInternalData(result.items);
70
+ onDataUpdate === null || onDataUpdate === void 0 ? void 0 : onDataUpdate(result.items);
71
+ }
72
+ }
73
+ catch (error) {
74
+ console.error('PopupList fetchData error:', error);
75
+ }
76
+ }
77
+ else if (localSearch) {
78
+ // Local filtering
79
+ const filtered = data.filter(item => item.title.toLowerCase().includes(newQuery.toLowerCase()));
80
+ setInternalData(filtered);
81
+ onDataUpdate === null || onDataUpdate === void 0 ? void 0 : onDataUpdate(filtered);
82
+ }
83
+ });
84
+ return unsubscribe;
85
+ }, [fetchData, localSearch, pageSize, data, onDataUpdate]);
86
+ const defaultRenderItem = useCallback(({ item, index }) => (<ListItem item={item} index={index} selectedItem={selectedItem} onItemPress={onItemPress} theme={theme} rootViewsRef={rootViewsRef} selectedItemBackgroundColor={selectedItemBackgroundColor}/>), [selectedItem, onItemPress, theme, rootViewsRef, selectedItemBackgroundColor]);
87
+ return (<View style={[styles.autoPositionedPopupList, { backgroundColor: theme.colors.background }]}>
88
+ <AdvancedFlatList data={internalData} keyExtractor={keyExtractor} renderItem={renderItem || defaultRenderItem} keyboardShouldPersistTaps="always" showsVerticalScrollIndicator={true} nestedScrollEnabled={true}/>
89
+ </View>);
90
+ });
91
+ // Main AutoPositionedPopup component
92
+ const AutoPositionedPopup = memo(forwardRef((props, parentRef) => {
93
+ const { tag, style, AutoPositionedPopupBtnStyle, placeholder = 'Please Select', textAlign = 'right', onSubmitEditing, TextInputProps = {}, inputStyle, labelStyle, popUpViewStyle = { left: '5%', width: '90%' }, fetchData, renderItem, onItemSelected, localSearch = false, pageSize = 20, selectedItem, useTextInput = false, btwChildren, CustomRow = ({ children }) => <View>{children}</View>, keyExtractor = (item) => item === null || item === void 0 ? void 0 : item.id, AutoPositionedPopupBtnDisabled = false, forceRemoveAllRootViewOnItemSelected = false, centerDisplay = false, selectedItemBackgroundColor = 'rgba(116, 116, 128, 0.08)', } = props;
94
+ // Use RootView context
95
+ const { addRootView, removeRootView, rootViews, searchQuery: contextSearchQuery, setSearchQuery: setContextSearchQuery } = useRootView();
96
+ const rootViewsRef = useRef(rootViews);
97
+ useEffect(() => {
98
+ rootViewsRef.current = rootViews;
99
+ }, [rootViews]);
100
+ // State management
101
+ const [isVisible, setIsVisible] = useState(false);
102
+ const [data, setData] = useState([]);
103
+ const [loading, setLoading] = useState(false);
104
+ const [popupPosition, setPopupPosition] = useState({ top: 0, left: 0, width: 0 });
105
+ const popupId = useRef(`popup-${tag}-${Date.now()}`);
106
+ // Refs for performance optimization
107
+ const containerRef = useRef(null);
108
+ const textInputRef = useRef(null);
109
+ const debounceTimerRef = useRef(null);
110
+ const searchQueryRef = useRef(''); // Use ref instead of state to avoid re-renders
111
+ // Constants
112
+ const LIST_HEIGHT = 200;
113
+ const theme = defaultTheme;
114
+ // Fetch data function
115
+ const loadData = useCallback(async (query = '') => {
116
+ if (!fetchData)
117
+ return;
118
+ setLoading(true);
119
+ try {
120
+ const result = await fetchData({
121
+ pageIndex: 0,
122
+ pageSize,
123
+ searchQuery: query,
124
+ });
125
+ if (result === null || result === void 0 ? void 0 : result.items) {
126
+ setData(result.items);
127
+ }
128
+ }
129
+ catch (error) {
130
+ console.error('Error loading data:', error);
131
+ }
132
+ finally {
133
+ setLoading(false);
134
+ }
135
+ }, [fetchData, pageSize]);
136
+ // Handle search query change with debounce and event emission
137
+ const handleSearchChange = useCallback((query) => {
138
+ // Store in ref to avoid re-renders
139
+ searchQueryRef.current = query;
140
+ // Update TextInput value directly if needed
141
+ if (textInputRef.current) {
142
+ // The TextInput's value will be controlled by its own state
143
+ }
144
+ // Clear previous debounce timer
145
+ if (debounceTimerRef.current) {
146
+ clearTimeout(debounceTimerRef.current);
147
+ }
148
+ // Use debounce for performance optimization
149
+ debounceTimerRef.current = setTimeout(() => {
150
+ // Emit query change event to decouple components and avoid context re-rendering
151
+ emitQueryChange(searchQueryRef.current);
152
+ }, 300); // Use 300ms debounce like the original
153
+ }, []);
154
+ // Calculate popup position
155
+ const calculatePosition = useCallback(() => {
156
+ if (!containerRef.current)
157
+ return;
158
+ containerRef.current.measureInWindow((x, y, width, height) => {
159
+ const screenHeight = Dimensions.get('screen').height;
160
+ const screenWidth = Dimensions.get('screen').width;
161
+ let top = y + height;
162
+ let left = x;
163
+ let popupWidth = width;
164
+ // Check if popup should appear above the input
165
+ if (y + height + LIST_HEIGHT > screenHeight) {
166
+ top = y - LIST_HEIGHT;
167
+ }
168
+ // Adjust horizontal position if needed
169
+ if ((popUpViewStyle === null || popUpViewStyle === void 0 ? void 0 : popUpViewStyle.left) && (popUpViewStyle === null || popUpViewStyle === void 0 ? void 0 : popUpViewStyle.width)) {
170
+ const leftPercent = parseFloat(String(popUpViewStyle.left).replace('%', '')) / 100;
171
+ const widthPercent = parseFloat(String(popUpViewStyle.width).replace('%', '')) / 100;
172
+ left = screenWidth * leftPercent;
173
+ popupWidth = screenWidth * widthPercent;
174
+ }
175
+ setPopupPosition({ top, left, width: popupWidth });
176
+ });
177
+ }, [popUpViewStyle]);
178
+ // Hide popup using RootView
179
+ const hidePopup = useCallback(() => {
180
+ var _a, _b;
181
+ setIsVisible(false);
182
+ // Reset search query
183
+ searchQueryRef.current = '';
184
+ if (textInputRef.current) {
185
+ textInputRef.current.blur();
186
+ (_b = (_a = textInputRef.current).clear) === null || _b === void 0 ? void 0 : _b.call(_a); // Clear the TextInput
187
+ }
188
+ removeRootView(popupId.current, forceRemoveAllRootViewOnItemSelected, rootViewsRef.current);
189
+ }, [removeRootView, forceRemoveAllRootViewOnItemSelected]);
190
+ // Handle data updates from PopupList
191
+ const handleDataUpdate = useCallback((newData) => {
192
+ setData(newData);
193
+ }, []);
194
+ // Handle item selection
195
+ const handleItemPress = useCallback((item) => {
196
+ onItemSelected === null || onItemSelected === void 0 ? void 0 : onItemSelected(item);
197
+ hidePopup();
198
+ }, [onItemSelected, hidePopup]);
199
+ // Show popup using RootView
200
+ const showPopup = useCallback(() => {
201
+ calculatePosition();
202
+ setIsVisible(true);
203
+ loadData(searchQueryRef.current);
204
+ // Wait for position to be calculated
205
+ setTimeout(() => {
206
+ const popupComponent = (<TouchableOpacity style={{
207
+ flex: 1,
208
+ backgroundColor: 'rgba(0, 0, 0, 0.3)',
209
+ }} activeOpacity={1} onPress={hidePopup}>
210
+ <View style={{
211
+ position: 'absolute',
212
+ top: popupPosition.top,
213
+ left: popupPosition.left,
214
+ width: popupPosition.width,
215
+ height: LIST_HEIGHT,
216
+ backgroundColor: theme.colors.background,
217
+ borderRadius: 8,
218
+ shadowColor: '#000',
219
+ shadowOffset: { width: 0, height: 2 },
220
+ shadowOpacity: 0.25,
221
+ shadowRadius: 3.84,
222
+ elevation: 5,
223
+ }}>
224
+ {useTextInput && (<RNTextInput ref={textInputRef} style={[
225
+ styles.inputStyle,
226
+ {
227
+ height: 40,
228
+ borderBottomWidth: 1,
229
+ borderBottomColor: theme.colors.border,
230
+ paddingHorizontal: 12,
231
+ color: theme.colors.text,
232
+ },
233
+ inputStyle,
234
+ ]} placeholder={placeholder} placeholderTextColor={theme.colors.placeholderText} defaultValue={searchQueryRef.current} onChangeText={handleSearchChange} onSubmitEditing={(e) => {
235
+ onSubmitEditing === null || onSubmitEditing === void 0 ? void 0 : onSubmitEditing(e);
236
+ Keyboard.dismiss();
237
+ }} returnKeyType="done" {...TextInputProps}/>)}
238
+
239
+ <PopupList data={data} selectedItem={selectedItem} onItemPress={handleItemPress} renderItem={renderItem} keyExtractor={keyExtractor} theme={theme} rootViewsRef={rootViewsRef} fetchData={fetchData} localSearch={localSearch} pageSize={pageSize} onDataUpdate={handleDataUpdate} selectedItemBackgroundColor={selectedItemBackgroundColor}/>
240
+ </View>
241
+ </TouchableOpacity>);
242
+ addRootView({
243
+ id: popupId.current,
244
+ style: {
245
+ position: 'absolute',
246
+ top: 0,
247
+ left: 0,
248
+ right: 0,
249
+ bottom: 0,
250
+ },
251
+ component: popupComponent,
252
+ useModal: true,
253
+ onModalClose: hidePopup,
254
+ centerDisplay: centerDisplay,
255
+ });
256
+ }, 100);
257
+ }, [calculatePosition, loadData, popupPosition, useTextInput, placeholder, theme, inputStyle, TextInputProps, data, selectedItem, renderItem, keyExtractor, centerDisplay, addRootView, hidePopup, handleSearchChange, handleItemPress, LIST_HEIGHT, selectedItemBackgroundColor]);
258
+ // Handle button press
259
+ const handleButtonPress = useCallback(() => {
260
+ if (AutoPositionedPopupBtnDisabled)
261
+ return;
262
+ if (useTextInput) {
263
+ showPopup();
264
+ // Focus text input after a short delay
265
+ setTimeout(() => {
266
+ var _a;
267
+ (_a = textInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
268
+ }, 100);
269
+ }
270
+ else {
271
+ showPopup();
272
+ }
273
+ }, [AutoPositionedPopupBtnDisabled, useTextInput, showPopup]);
274
+ // Imperative handle for parent component access
275
+ useImperativeHandle(parentRef, () => ({
276
+ clearSelectedItem: () => {
277
+ // Clear selection logic can be implemented here
278
+ console.log('Clearing selected item for:', tag);
279
+ },
280
+ showPopup,
281
+ hidePopup,
282
+ }), [tag, showPopup, hidePopup]);
283
+ // Cleanup
284
+ useEffect(() => {
285
+ return () => {
286
+ if (debounceTimerRef.current) {
287
+ clearTimeout(debounceTimerRef.current);
288
+ }
289
+ };
290
+ }, []);
291
+ // Render the component
292
+ return (<CustomRow>
293
+ <View style={[styles.contain, style]} ref={containerRef}>
294
+ <TouchableOpacity style={[styles.AutoPositionedPopupBtn, AutoPositionedPopupBtnStyle]} disabled={AutoPositionedPopupBtnDisabled} onPress={handleButtonPress}>
295
+ {btwChildren ? (btwChildren()) : (<Text style={[
296
+ styles.searchQueryTxt,
297
+ selectedItem && { color: theme.colors.text },
298
+ labelStyle,
299
+ ]} numberOfLines={1} ellipsizeMode="tail">
300
+ {(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.title) || placeholder}
301
+ </Text>)}
302
+ </TouchableOpacity>
303
+ </View>
304
+ </CustomRow>);
305
+ }));
306
+ export default AutoPositionedPopup;
@@ -0,0 +1,80 @@
1
+ declare const _default: {
2
+ des: {
3
+ fontSize: number;
4
+ lineHeight: number;
5
+ fontWeight: "400";
6
+ color: string;
7
+ marginLeft: number;
8
+ };
9
+ ListItemCode: {
10
+ fontSize: number;
11
+ lineHeight: number;
12
+ fontWeight: "600";
13
+ color: string;
14
+ };
15
+ commonModalRow: {
16
+ height: number;
17
+ borderBottomWidth: number;
18
+ overflow: "hidden";
19
+ alignItems: "center";
20
+ justifyContent: "center";
21
+ width: "100%";
22
+ flexDirection: "row";
23
+ borderRadius: number;
24
+ };
25
+ autoPositionedPopupList: {
26
+ flex: number;
27
+ height: "100%";
28
+ padding: number;
29
+ };
30
+ inputStyle: {
31
+ fontSize: number;
32
+ fontWeight: "400";
33
+ lineHeight: number;
34
+ color: string;
35
+ width: "90%";
36
+ textAlign: "right";
37
+ };
38
+ AutoPositionedPopupBtn: {
39
+ flex: number;
40
+ flexDirection: "row";
41
+ alignItems: "center";
42
+ };
43
+ searchQueryTxt: {
44
+ fontSize: number;
45
+ lineHeight: number;
46
+ color: string;
47
+ textAlign: "right";
48
+ };
49
+ contain: {
50
+ flex: number;
51
+ height: "100%";
52
+ };
53
+ selectArrow: {
54
+ marginLeft: number;
55
+ marginRight: number;
56
+ width: number;
57
+ height: number;
58
+ };
59
+ AutoDropdownBtnStyle1: {
60
+ justifyContent: "flex-start";
61
+ };
62
+ AutoDropdownBtnStyle: {
63
+ justifyContent: "flex-end";
64
+ };
65
+ usageRowText: {
66
+ fontSize: number;
67
+ lineHeight: number;
68
+ fontWeight: "400";
69
+ color: string;
70
+ };
71
+ AutoDropdownRow: {
72
+ flex: number;
73
+ height: number;
74
+ flexDirection: "row";
75
+ alignItems: "center";
76
+ justifyContent: "space-between";
77
+ };
78
+ };
79
+ export default _default;
80
+ //# sourceMappingURL=AutoPositionedPopup.style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoPositionedPopup.style.d.ts","sourceRoot":"","sources":["../src/AutoPositionedPopup.style.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,wBA6EG"}
@@ -0,0 +1,79 @@
1
+ import { StyleSheet } from 'react-native';
2
+ export default StyleSheet.create({
3
+ des: {
4
+ fontSize: 12,
5
+ lineHeight: 20,
6
+ fontWeight: '400',
7
+ color: '#666666',
8
+ marginLeft: 4,
9
+ },
10
+ ListItemCode: {
11
+ fontSize: 15,
12
+ lineHeight: 20,
13
+ fontWeight: '600',
14
+ color: '#333333',
15
+ },
16
+ commonModalRow: {
17
+ height: 32,
18
+ borderBottomWidth: 0,
19
+ overflow: 'hidden',
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ width: '100%',
23
+ flexDirection: 'row',
24
+ borderRadius: 8,
25
+ },
26
+ autoPositionedPopupList: {
27
+ flex: 1,
28
+ height: '100%',
29
+ padding: 12,
30
+ },
31
+ inputStyle: {
32
+ fontSize: 15,
33
+ fontWeight: '400',
34
+ lineHeight: 20,
35
+ color: '#333333',
36
+ width: '90%',
37
+ textAlign: 'right',
38
+ },
39
+ AutoPositionedPopupBtn: {
40
+ flex: 1,
41
+ flexDirection: 'row',
42
+ alignItems: 'center',
43
+ },
44
+ searchQueryTxt: {
45
+ fontSize: 17,
46
+ lineHeight: 24,
47
+ color: '#999999',
48
+ textAlign: 'right',
49
+ },
50
+ contain: {
51
+ flex: 1,
52
+ height: '100%',
53
+ },
54
+ selectArrow: {
55
+ marginLeft: 6,
56
+ marginRight: 8,
57
+ width: 8,
58
+ height: 14,
59
+ },
60
+ AutoDropdownBtnStyle1: {
61
+ justifyContent: 'flex-start',
62
+ },
63
+ AutoDropdownBtnStyle: {
64
+ justifyContent: 'flex-end',
65
+ },
66
+ usageRowText: {
67
+ fontSize: 17,
68
+ lineHeight: 21,
69
+ fontWeight: '400',
70
+ color: '#333333',
71
+ },
72
+ AutoDropdownRow: {
73
+ flex: 1,
74
+ height: 50,
75
+ flexDirection: 'row',
76
+ alignItems: 'center',
77
+ justifyContent: 'space-between',
78
+ },
79
+ });
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { StyleProp, TextInputProps, TextStyle, ViewStyle } from 'react-native';
3
+ import { TextInputSubmitEditingEventData } from 'react-native/Libraries/Components/TextInput/TextInput';
4
+ import { NativeSyntheticEvent } from 'react-native/Libraries/Types/CoreEventTypes';
5
+ export interface Data {
6
+ items: any[];
7
+ pageIndex: number;
8
+ needLoadMore: boolean;
9
+ }
10
+ export interface SelectedItem {
11
+ id: string;
12
+ title: string;
13
+ }
14
+ /**
15
+ * Props interface for AutoPositionedPopup component
16
+ */
17
+ export interface AutoPositionedPopupProps {
18
+ style?: ViewStyle;
19
+ labelStyle?: ViewStyle;
20
+ tag: string;
21
+ tagStyle?: ViewStyle;
22
+ fetchData?: ({ pageIndex, pageSize, searchQuery, }: {
23
+ pageIndex: number;
24
+ pageSize: number;
25
+ searchQuery?: string;
26
+ }) => Promise<Data | null>;
27
+ renderItem?: ({ item, index }: {
28
+ item: SelectedItem;
29
+ index: number;
30
+ }) => React.ReactElement;
31
+ onItemSelected?: (item: SelectedItem) => void;
32
+ onSubmitEditing?: (e: NativeSyntheticEvent<TextInputSubmitEditingEventData>) => void;
33
+ localSearch?: boolean;
34
+ placeholder?: string;
35
+ textAlign?: 'left' | 'center' | 'right' | undefined;
36
+ pageSize?: number;
37
+ selectedItem?: SelectedItem | any;
38
+ CustomRow?: React.ComponentType<ViewStyle & {
39
+ children?: React.ReactNode;
40
+ }>;
41
+ btwChildren?: () => React.ReactNode;
42
+ useTextInput?: boolean;
43
+ keyExtractor?: (item: SelectedItem) => string;
44
+ CustomPopView?: () => React.ComponentType<ViewStyle & {
45
+ children?: React.ReactNode;
46
+ selectedItem?: SelectedItem | any;
47
+ }>;
48
+ CustomPopViewStyle?: ViewStyle;
49
+ forceRemoveAllRootViewOnItemSelected?: boolean;
50
+ inputStyle?: StyleProp<TextStyle>;
51
+ TextInputProps?: TextInputProps;
52
+ popUpViewStyle?: ViewStyle;
53
+ AutoPositionedPopupBtnStyle?: ViewStyle;
54
+ AutoPositionedPopupBtnDisabled?: boolean;
55
+ centerDisplay?: boolean;
56
+ selectedItemBackgroundColor?: string;
57
+ }
58
+ //# sourceMappingURL=AutoPositionedPopupProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutoPositionedPopupProps.d.ts","sourceRoot":"","sources":["../src/AutoPositionedPopupProps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,+BAA+B,EAAE,MAAM,uDAAuD,CAAC;AACxG,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAEnF,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,EACX,SAAS,EACT,QAAQ,EACR,WAAW,GACZ,EAAE;QACD,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC3B,UAAU,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,KAAK,CAAC,YAAY,CAAC;IAC5F,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAC9C,eAAe,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,CAAC,+BAA+B,CAAC,KAAK,IAAI,CAAC;IACrF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,GAAG,GAAG,CAAC;IAClC,SAAS,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,SAAS,GAAG;QAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;IAC5E,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,MAAM,CAAC;IAC9C,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,aAAa,CACvC,SAAS,GAAG;QACV,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;QAC3B,YAAY,CAAC,EAAE,YAAY,GAAG,GAAG,CAAC;KACnC,CACF,CAAC;IACF,kBAAkB,CAAC,EAAE,SAAS,CAAC;IAC/B,oCAAoC,CAAC,EAAE,OAAO,CAAC;IAC/C,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,2BAA2B,CAAC,EAAE,SAAS,CAAC;IACxC,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import React, { ReactNode } from 'react';
2
+ import { ViewStyle } from 'react-native';
3
+ interface DynamicViewBase {
4
+ id: string;
5
+ style: ViewStyle;
6
+ component: ReactNode;
7
+ useModal?: boolean;
8
+ onModalClose?: () => void;
9
+ centerDisplay?: boolean;
10
+ }
11
+ interface RootViewContextType {
12
+ addRootView: (view: DynamicViewBase) => void;
13
+ setRootViewNativeStyle: (id: string, style: ViewStyle) => void;
14
+ updateRootView: (id: string, update: Partial<DynamicViewBase>) => void;
15
+ removeRootView: (id?: string, force?: boolean, _rootViews?: DynamicViewBase[]) => void;
16
+ rootViews: DynamicViewBase[];
17
+ searchQuery: string;
18
+ setSearchQuery: (searchQuery: string) => void;
19
+ }
20
+ interface RootViewProviderProps {
21
+ children: ReactNode;
22
+ }
23
+ /**
24
+ * Dynamically add or remove views on the root view.
25
+ * @param children
26
+ * @constructor
27
+ */
28
+ export declare const RootViewProvider: React.FC<RootViewProviderProps>;
29
+ export declare const useRootView: () => RootViewContextType;
30
+ export {};
31
+ //# sourceMappingURL=RootViewContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RootViewContext.d.ts","sourceRoot":"","sources":["../src/RootViewContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAmE,MAAM,OAAO,CAAC;AAC1G,OAAO,EAAmB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE1D,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,mBAAmB;IAC3B,WAAW,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7C,sBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC/D,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IACvE,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IACvF,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAGD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA+I5D,CAAC;AAIF,eAAO,MAAM,WAAW,QAAO,mBAM9B,CAAC"}