@utilitywarehouse/hearth-react-native 0.28.6 → 0.29.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.
Files changed (47) hide show
  1. package/.storybook/preview.tsx +7 -4
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.turbo/turbo-lint.log +15 -18
  4. package/CHANGELOG.md +44 -0
  5. package/build/components/Combobox/Combobox.js +1 -1
  6. package/build/components/Modal/Modal.d.ts +1 -1
  7. package/build/components/Modal/Modal.js +6 -95
  8. package/build/components/Modal/Modal.props.d.ts +2 -31
  9. package/build/components/Modal/Modal.shared.types.d.ts +22 -0
  10. package/build/components/Modal/Modal.web.d.ts +1 -1
  11. package/build/components/Modal/Modal.web.js +6 -71
  12. package/build/components/NavModal/NavModal.d.ts +3 -0
  13. package/build/components/NavModal/NavModal.js +190 -0
  14. package/build/components/NavModal/NavModal.props.d.ts +15 -0
  15. package/build/components/NavModal/NavModal.props.js +1 -0
  16. package/build/components/NavModal/index.d.ts +2 -0
  17. package/build/components/NavModal/index.js +1 -0
  18. package/build/components/Select/Select.js +1 -1
  19. package/build/components/index.d.ts +2 -1
  20. package/build/components/index.js +2 -1
  21. package/docs/changelog.mdx +34 -0
  22. package/docs/components/AllComponents.web.tsx +709 -689
  23. package/package.json +3 -1
  24. package/src/components/Combobox/Combobox.tsx +1 -1
  25. package/src/components/Modal/Modal.docs.mdx +5 -122
  26. package/src/components/Modal/Modal.props.ts +2 -34
  27. package/src/components/Modal/Modal.shared.types.ts +23 -0
  28. package/src/components/Modal/Modal.stories.tsx +0 -1
  29. package/src/components/Modal/Modal.tsx +11 -174
  30. package/src/components/Modal/Modal.web.tsx +29 -127
  31. package/src/components/NavModal/NavModal.docs.mdx +178 -0
  32. package/src/components/NavModal/NavModal.figma.tsx +13 -0
  33. package/src/components/NavModal/NavModal.props.ts +23 -0
  34. package/src/components/NavModal/NavModal.stories.tsx +131 -0
  35. package/src/components/NavModal/NavModal.tsx +375 -0
  36. package/src/components/NavModal/index.ts +2 -0
  37. package/src/components/Select/Select.tsx +1 -1
  38. package/src/components/index.ts +3 -1
  39. package/build/components/SafeAreaView/SafeAreaView.d.ts +0 -5
  40. package/build/components/SafeAreaView/SafeAreaView.js +0 -117
  41. package/build/components/SafeAreaView/SafeAreaView.props.d.ts +0 -17
  42. package/build/components/SafeAreaView/index.d.ts +0 -2
  43. package/build/components/SafeAreaView/index.js +0 -1
  44. package/src/components/SafeAreaView/SafeAreaView.props.ts +0 -20
  45. package/src/components/SafeAreaView/SafeAreaView.tsx +0 -173
  46. package/src/components/SafeAreaView/index.ts +0 -2
  47. /package/build/components/{SafeAreaView/SafeAreaView.props.js → Modal/Modal.shared.types.js} +0 -0
@@ -0,0 +1,375 @@
1
+ import { CloseMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
2
+ import { useCallback, useEffect, useImperativeHandle, useMemo } from 'react';
3
+ import { Platform, ScrollView, View } from 'react-native';
4
+ import Animated, {
5
+ Easing,
6
+ useAnimatedStyle,
7
+ useSharedValue,
8
+ withDelay,
9
+ withTiming,
10
+ } from 'react-native-reanimated';
11
+ import { SafeAreaView } from 'react-native-safe-area-context';
12
+ import { StyleSheet } from 'react-native-unistyles';
13
+ import { useTheme } from '../../hooks';
14
+ import { hexWithOpacity } from '../../utils';
15
+ import { BodyText } from '../BodyText';
16
+ import { Button } from '../Button';
17
+ import { Heading } from '../Heading';
18
+ import { Spinner } from '../Spinner';
19
+ import { UnstyledIconButton } from '../UnstyledIconButton';
20
+ import NavModalProps from './NavModal.props';
21
+
22
+ const NavModal = ({
23
+ ref,
24
+ children,
25
+ heading,
26
+ description,
27
+ showCloseButton = true,
28
+ primaryButtonText,
29
+ secondaryButtonText,
30
+ onPressPrimaryButton,
31
+ onPressCloseButton,
32
+ onPressSecondaryButton,
33
+ loading,
34
+ loadingHeading = 'Loading...',
35
+ image,
36
+ primaryButtonProps,
37
+ secondaryButtonProps,
38
+ closeButtonProps,
39
+ stickyFooter = true,
40
+ background = 'default',
41
+ scrollable = true,
42
+ presentation = 'modal',
43
+ scrollViewProps,
44
+ safeAreaViewProps,
45
+ ...props
46
+ }: NavModalProps) => {
47
+ const theme = useTheme();
48
+ const backgroundOpacity = useSharedValue(0);
49
+ const pretendContentTranslateY = useSharedValue(20);
50
+ const isBrandBackground = background === 'brand';
51
+ const isFullScreenPresentation = presentation === 'fullScreenModal';
52
+ const usesSheetPresentation = !isFullScreenPresentation;
53
+
54
+ const triggerCloseAnimation = useCallback(() => {
55
+ if (Platform.OS === 'android') {
56
+ pretendContentTranslateY.value = withTiming(20, {
57
+ duration: 50,
58
+ easing: Easing.in(Easing.quad),
59
+ });
60
+ backgroundOpacity.value = withTiming(0, {
61
+ duration: 100,
62
+ easing: Easing.in(Easing.quad),
63
+ });
64
+ }
65
+ }, [backgroundOpacity, pretendContentTranslateY]);
66
+
67
+ useImperativeHandle(ref, () => ({
68
+ triggerCloseAnimation,
69
+ }));
70
+
71
+ useEffect(() => {
72
+ if (Platform.OS === 'android') {
73
+ backgroundOpacity.value = withDelay(
74
+ 300,
75
+ withTiming(1, {
76
+ duration: 200,
77
+ easing: Easing.out(Easing.quad),
78
+ })
79
+ );
80
+ pretendContentTranslateY.value = withDelay(
81
+ 500,
82
+ withTiming(0, {
83
+ duration: 300,
84
+ easing: Easing.out(Easing.quad),
85
+ })
86
+ );
87
+ }
88
+ }, [backgroundOpacity, pretendContentTranslateY]);
89
+
90
+ const animatedBackgroundStyle = useAnimatedStyle(() => ({
91
+ backgroundColor: hexWithOpacity(
92
+ theme.components.overlay.backgroundColor,
93
+ backgroundOpacity.value * (theme.components.overlay.opacity / 100)
94
+ ),
95
+ }));
96
+
97
+ const animatedPretendContentStyle = useAnimatedStyle(() => ({
98
+ transform: [{ translateY: pretendContentTranslateY.value }],
99
+ }));
100
+
101
+ const handleCloseButtonPress = useCallback(() => {
102
+ onPressCloseButton?.();
103
+ }, [onPressCloseButton]);
104
+
105
+ const handlePrimaryButtonPress = useCallback(() => {
106
+ onPressPrimaryButton?.();
107
+ }, [onPressPrimaryButton]);
108
+
109
+ const handleSecondaryButtonPress = useCallback(() => {
110
+ onPressSecondaryButton?.();
111
+ }, [onPressSecondaryButton]);
112
+
113
+ const noButtons = !onPressPrimaryButton && !onPressSecondaryButton;
114
+
115
+ styles.useVariants({
116
+ loading,
117
+ background: isBrandBackground ? 'brand' : 'primary',
118
+ presentation: isFullScreenPresentation ? 'fullScreen' : 'modal',
119
+ });
120
+
121
+ const footer = useMemo(
122
+ () => (
123
+ <View style={styles.footer}>
124
+ {onPressPrimaryButton && primaryButtonText ? (
125
+ <Button
126
+ onPress={handlePrimaryButtonPress}
127
+ text={primaryButtonText}
128
+ inverted={isBrandBackground}
129
+ {...primaryButtonProps}
130
+ variant={(primaryButtonProps?.variant as 'solid') ?? 'solid'}
131
+ colorScheme={(primaryButtonProps?.colorScheme as 'highlight') ?? 'highlight'}
132
+ />
133
+ ) : null}
134
+ {onPressSecondaryButton && secondaryButtonText ? (
135
+ <Button
136
+ onPress={handleSecondaryButtonPress}
137
+ text={secondaryButtonText}
138
+ inverted={isBrandBackground}
139
+ {...secondaryButtonProps}
140
+ variant={(secondaryButtonProps?.variant as 'outline') ?? 'outline'}
141
+ colorScheme={(secondaryButtonProps?.colorScheme as 'functional') ?? 'functional'}
142
+ />
143
+ ) : null}
144
+ </View>
145
+ ),
146
+ [
147
+ handlePrimaryButtonPress,
148
+ handleSecondaryButtonPress,
149
+ isBrandBackground,
150
+ onPressPrimaryButton,
151
+ onPressSecondaryButton,
152
+ primaryButtonProps,
153
+ primaryButtonText,
154
+ secondaryButtonProps,
155
+ secondaryButtonText,
156
+ ]
157
+ );
158
+
159
+ const content = (
160
+ <>
161
+ {loading ? (
162
+ <View
163
+ style={styles.loadingContainer}
164
+ accessible={Platform.OS === 'android' ? true : undefined}
165
+ accessibilityLabel={Platform.OS === 'android' ? 'Loading' : undefined}
166
+ screenReaderFocusable
167
+ >
168
+ <Spinner size="lg" color={isBrandBackground ? theme.color.icon.inverted : undefined} />
169
+ <Heading size="lg" textAlign="center" inverted={isBrandBackground}>
170
+ {loadingHeading}
171
+ </Heading>
172
+ </View>
173
+ ) : (
174
+ <View
175
+ style={styles.container}
176
+ accessible={Platform.OS === 'android' ? true : undefined}
177
+ accessibilityLabel={Platform.OS === 'android' ? 'Modal content' : undefined}
178
+ screenReaderFocusable
179
+ >
180
+ <View style={styles.header}>
181
+ <View style={styles.headerTextContent}>
182
+ {heading && !image ? (
183
+ <Heading size="lg" accessible inverted={isBrandBackground}>
184
+ {heading}
185
+ </Heading>
186
+ ) : null}
187
+ {description && !image ? (
188
+ <BodyText accessible inverted={isBrandBackground}>
189
+ {description}
190
+ </BodyText>
191
+ ) : null}
192
+ </View>
193
+ {showCloseButton ? (
194
+ <UnstyledIconButton
195
+ icon={CloseMediumIcon}
196
+ onPress={handleCloseButtonPress}
197
+ accessibilityLabel="Close modal"
198
+ inverted={isBrandBackground}
199
+ {...closeButtonProps}
200
+ />
201
+ ) : null}
202
+ </View>
203
+ {image ? (
204
+ <View style={styles.imageContainer}>
205
+ {image}
206
+ <View style={styles.textContent}>
207
+ {heading ? (
208
+ <Heading size="lg" textAlign="center" accessible inverted={isBrandBackground}>
209
+ {heading}
210
+ </Heading>
211
+ ) : null}
212
+ {description ? (
213
+ <BodyText textAlign="center" accessible inverted={isBrandBackground}>
214
+ {description}
215
+ </BodyText>
216
+ ) : null}
217
+ </View>
218
+ </View>
219
+ ) : null}
220
+ {scrollable ? (
221
+ <ScrollView
222
+ style={{
223
+ flex: stickyFooter ? 1 : 0,
224
+ marginHorizontal: -4,
225
+ }}
226
+ contentContainerStyle={{ paddingHorizontal: 4 }}
227
+ {...scrollViewProps}
228
+ >
229
+ {children}
230
+ {!stickyFooter && !noButtons ? (
231
+ <View style={styles.inNavModalFooterContainer}>{footer}</View>
232
+ ) : null}
233
+ </ScrollView>
234
+ ) : (
235
+ <View
236
+ style={{
237
+ flex: stickyFooter ? 1 : 0,
238
+ }}
239
+ >
240
+ {children}
241
+ {!stickyFooter && !noButtons ? (
242
+ <View style={styles.inNavModalFooterContainer}>{footer}</View>
243
+ ) : null}
244
+ </View>
245
+ )}
246
+ {stickyFooter && !noButtons ? footer : null}
247
+ </View>
248
+ )}
249
+ </>
250
+ );
251
+
252
+ const { style: safeAreaViewStyle, ...restSafeAreaViewProps } = safeAreaViewProps ?? {};
253
+
254
+ return (
255
+ <SafeAreaView
256
+ style={[
257
+ {
258
+ flex: 1,
259
+ backgroundColor: theme.color.background[isBrandBackground ? 'brand' : 'secondary'],
260
+ },
261
+ safeAreaViewStyle,
262
+ ]}
263
+ {...restSafeAreaViewProps}
264
+ >
265
+ {Platform.OS === 'android' && usesSheetPresentation ? (
266
+ <Animated.View style={[styles.androidContainer, animatedBackgroundStyle]}>
267
+ <Animated.View style={[styles.pretendContent, animatedPretendContentStyle]} />
268
+ </Animated.View>
269
+ ) : null}
270
+ <Animated.View
271
+ style={[
272
+ styles.inNavModalContainer,
273
+ Platform.OS === 'android' && usesSheetPresentation && animatedBackgroundStyle,
274
+ ]}
275
+ {...props}
276
+ >
277
+ <View style={styles.inNavModalContent}>{content}</View>
278
+ </Animated.View>
279
+ </SafeAreaView>
280
+ );
281
+ };
282
+
283
+ const styles = StyleSheet.create((theme, rt) => ({
284
+ container: {
285
+ flex: 1,
286
+ gap: theme.components.modal.gap,
287
+ variants: {
288
+ loading: {
289
+ true: {
290
+ paddingTop: 0,
291
+ },
292
+ },
293
+ },
294
+ },
295
+ header: {
296
+ flexDirection: 'row',
297
+ gap: theme.components.modal.gap,
298
+ },
299
+ headerTextContent: {
300
+ flex: 1,
301
+ gap: theme.components.modal.content.gap,
302
+ },
303
+ imageContainer: {
304
+ alignItems: 'center',
305
+ flex: 1,
306
+ },
307
+ textContent: {
308
+ gap: theme.components.modal.content.gap,
309
+ },
310
+ loadingContainer: {
311
+ borderTopLeftRadius: theme.components.modal.borderRadius,
312
+ borderTopRightRadius: theme.components.modal.borderRadius,
313
+ flex: 1,
314
+ alignItems: 'center',
315
+ justifyContent: 'center',
316
+ minHeight: 140,
317
+ gap: theme.components.modal.content.gap,
318
+ },
319
+ footer: {
320
+ gap: theme.components.modal.action.gap,
321
+ },
322
+ inNavModalContainer: {
323
+ flex: 1,
324
+ variants: {
325
+ presentation: {
326
+ modal: {
327
+ ...(Platform.OS === 'ios'
328
+ ? { backgroundColor: theme.components.overlay.backgroundColor }
329
+ : {}),
330
+ },
331
+ fullScreen: {},
332
+ },
333
+ },
334
+ },
335
+ inNavModalContent: {
336
+ flex: 1,
337
+ variants: {
338
+ background: {
339
+ primary: {},
340
+ brand: {
341
+ backgroundColor: theme.color.background.brand,
342
+ },
343
+ },
344
+ presentation: {
345
+ modal: {
346
+ borderTopLeftRadius: theme.components.modal.borderRadius,
347
+ borderTopRightRadius: theme.components.modal.borderRadius,
348
+ backgroundColor: theme.color.surface.neutral.strong,
349
+ padding: theme.components.bottomSheet.padding,
350
+ },
351
+ fullScreen: {
352
+ backgroundColor: theme.color.surface.neutral.strong,
353
+ padding: theme.components.bottomSheet.padding,
354
+ },
355
+ },
356
+ },
357
+ },
358
+ inNavModalFooterContainer: {
359
+ paddingTop: theme.components.modal.padding,
360
+ },
361
+ androidContainer: {
362
+ height: rt.insets.top + 18,
363
+ paddingLeft: theme.components.modal.padding,
364
+ paddingRight: theme.components.modal.padding,
365
+ justifyContent: 'flex-end',
366
+ },
367
+ pretendContent: {
368
+ borderTopLeftRadius: theme.components.modal.borderRadius,
369
+ borderTopRightRadius: theme.components.modal.borderRadius,
370
+ height: 12,
371
+ backgroundColor: theme.components.parts.modalStack.backgroundColorCardTop,
372
+ },
373
+ }));
374
+
375
+ export default NavModal;
@@ -0,0 +1,2 @@
1
+ export { default as NavModal } from './NavModal';
2
+ export type { default as NavModalProps, NavModalRef } from './NavModal.props';
@@ -1,6 +1,7 @@
1
1
  import { ExpandSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
2
2
  import React, { useCallback, useRef, useState } from 'react';
3
3
  import { Pressable, View } from 'react-native';
4
+ import { SafeAreaView } from 'react-native-safe-area-context';
4
5
  import { StyleSheet } from 'react-native-unistyles';
5
6
  import { BodyText } from '../BodyText';
6
7
  import {
@@ -16,7 +17,6 @@ import { Input } from '../Input';
16
17
  import { SelectContext } from './Select.context';
17
18
  import SelectProps, { SelectOptionItemProps } from './Select.props';
18
19
  import SelectOption from './SelectOption';
19
- import { SafeAreaView } from '../SafeAreaView';
20
20
 
21
21
  const Select = ({
22
22
  options = [],
@@ -41,13 +41,13 @@ export * from './Link';
41
41
  export * from './List';
42
42
  export * from './Menu';
43
43
  export * from './Modal';
44
+ export * from './NavModal';
44
45
  export * from './Pagination';
45
46
  export * from './PillGroup';
46
47
  export * from './ProgressBar';
47
48
  export * from './ProgressStepper';
48
49
  export * from './Radio';
49
50
  export * from './RadioCard';
50
- export * from './SafeAreaView';
51
51
  export * from './SectionHeader';
52
52
  export * from './SegmentedControl';
53
53
  export * from './Select';
@@ -69,4 +69,6 @@ export { FlatList, Image, KeyboardAvoidingView, ScrollView, SectionList, View }
69
69
 
70
70
  export { Pressable } from 'react-native';
71
71
 
72
+ export { SafeAreaView } from 'react-native-safe-area-context';
73
+
72
74
  export { createIcon } from '@gluestack-ui/icon';
@@ -1,5 +0,0 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
3
- import SafeAreaViewProps from './SafeAreaView.props';
4
- declare const SafeAreaView: React.ForwardRefExoticComponent<SafeAreaViewProps & React.RefAttributes<View>>;
5
- export default SafeAreaView;
@@ -1,117 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- import { StyleSheet as RNStyleSheet, useWindowDimensions, View, } from 'react-native';
4
- import { UnistylesRuntime } from '../../core';
5
- const DEFAULT_EDGES = ['top', 'right', 'bottom', 'left'];
6
- const EMPTY_INSETS = { top: 0, right: 0, bottom: 0, left: 0 };
7
- const EDGE_EPSILON = 1;
8
- const getNumericStyleValue = (value) => {
9
- return typeof value === 'number' ? value : 0;
10
- };
11
- const getStyleInsetValue = (style, mode, edge) => {
12
- const prefix = mode === 'margin' ? 'margin' : 'padding';
13
- if (!style) {
14
- // No style specified at all; treat as zero inset for safe-area calculations.
15
- return 0;
16
- }
17
- if (edge === 'top') {
18
- const raw = style[`${prefix}Top`] ?? style[`${prefix}Vertical`] ?? style[prefix];
19
- if (raw == null) {
20
- return 0;
21
- }
22
- return getNumericStyleValue(raw);
23
- }
24
- if (edge === 'bottom') {
25
- const raw = style[`${prefix}Bottom`] ?? style[`${prefix}Vertical`] ?? style[prefix];
26
- if (raw == null) {
27
- return 0;
28
- }
29
- return getNumericStyleValue(raw);
30
- }
31
- if (edge === 'left') {
32
- const raw = style[`${prefix}Left`] ?? style[`${prefix}Horizontal`] ?? style[prefix];
33
- if (raw == null) {
34
- return 0;
35
- }
36
- return getNumericStyleValue(raw);
37
- }
38
- const raw = style[`${prefix}Right`] ?? style[`${prefix}Horizontal`] ?? style[prefix];
39
- if (raw == null) {
40
- return 0;
41
- }
42
- return getNumericStyleValue(raw);
43
- };
44
- const SafeAreaView = forwardRef(({ children, edges = DEFAULT_EDGES, mode = 'padding', onLayout, style, ...props }, ref) => {
45
- const viewRef = useRef(null);
46
- const { width: windowWidth, height: windowHeight } = useWindowDimensions();
47
- const [edgeInsets, setEdgeInsets] = useState(EMPTY_INSETS);
48
- const flattenedStyle = useMemo(() => RNStyleSheet.flatten(style), [style]);
49
- const updateEdgeInsets = useCallback(() => {
50
- const currentView = viewRef.current;
51
- if (!currentView) {
52
- return;
53
- }
54
- currentView.measureInWindow((x, y, width, height) => {
55
- const runtimeInsets = UnistylesRuntime.insets ?? EMPTY_INSETS;
56
- const nextEdgeInsets = {
57
- top: edges.includes('top') ? Math.max(runtimeInsets.top - Math.max(y, 0), 0) : 0,
58
- right: edges.includes('right')
59
- ? Math.max(runtimeInsets.right - Math.max(windowWidth - (x + width), 0), 0)
60
- : 0,
61
- bottom: edges.includes('bottom')
62
- ? Math.max(runtimeInsets.bottom - Math.max(windowHeight - (y + height), 0), 0)
63
- : 0,
64
- left: edges.includes('left') ? Math.max(runtimeInsets.left - Math.max(x, 0), 0) : 0,
65
- };
66
- setEdgeInsets(previousInsets => {
67
- const hasChanged = Object.keys(nextEdgeInsets).some(edge => Math.abs(previousInsets[edge] - nextEdgeInsets[edge]) > EDGE_EPSILON);
68
- return hasChanged ? nextEdgeInsets : previousInsets;
69
- });
70
- });
71
- }, [edges, windowHeight, windowWidth]);
72
- useEffect(() => {
73
- const frame = requestAnimationFrame(updateEdgeInsets);
74
- return () => cancelAnimationFrame(frame);
75
- }, [updateEdgeInsets]);
76
- const handleRef = useCallback((node) => {
77
- viewRef.current = node;
78
- if (typeof ref === 'function') {
79
- ref(node);
80
- }
81
- else if (ref) {
82
- ref.current = node;
83
- }
84
- }, [ref]);
85
- const handleLayout = useCallback((event) => {
86
- onLayout?.(event);
87
- requestAnimationFrame(updateEdgeInsets);
88
- }, [onLayout, updateEdgeInsets]);
89
- const safeAreaStyle = useMemo(() => {
90
- const nextStyle = {};
91
- if (mode === 'padding') {
92
- nextStyle.paddingTop = getStyleInsetValue(flattenedStyle, mode, 'top') + edgeInsets.top;
93
- nextStyle.paddingRight =
94
- getStyleInsetValue(flattenedStyle, mode, 'right') + edgeInsets.right;
95
- nextStyle.paddingBottom =
96
- getStyleInsetValue(flattenedStyle, mode, 'bottom') + edgeInsets.bottom;
97
- nextStyle.paddingLeft = getStyleInsetValue(flattenedStyle, mode, 'left') + edgeInsets.left;
98
- return nextStyle;
99
- }
100
- nextStyle.marginTop = getStyleInsetValue(flattenedStyle, mode, 'top') + edgeInsets.top;
101
- nextStyle.marginRight = getStyleInsetValue(flattenedStyle, mode, 'right') + edgeInsets.right;
102
- nextStyle.marginBottom =
103
- getStyleInsetValue(flattenedStyle, mode, 'bottom') + edgeInsets.bottom;
104
- nextStyle.marginLeft = getStyleInsetValue(flattenedStyle, mode, 'left') + edgeInsets.left;
105
- return nextStyle;
106
- }, [
107
- edgeInsets.bottom,
108
- edgeInsets.left,
109
- edgeInsets.right,
110
- edgeInsets.top,
111
- flattenedStyle,
112
- mode,
113
- ]);
114
- return (_jsx(View, { ref: handleRef, onLayout: handleLayout, style: [style, safeAreaStyle], ...props, children: children }));
115
- });
116
- SafeAreaView.displayName = 'SafeAreaView';
117
- export default SafeAreaView;
@@ -1,17 +0,0 @@
1
- import { ViewProps } from 'react-native';
2
- export type SafeAreaEdge = 'top' | 'right' | 'bottom' | 'left';
3
- interface SafeAreaViewProps extends ViewProps {
4
- /**
5
- * Which edges should receive safe area compensation.
6
- *
7
- * @default ['top', 'right', 'bottom', 'left']
8
- */
9
- edges?: SafeAreaEdge[];
10
- /**
11
- * Whether safe area compensation should be applied as padding or margin.
12
- *
13
- * @default 'padding'
14
- */
15
- mode?: 'padding' | 'margin';
16
- }
17
- export default SafeAreaViewProps;
@@ -1,2 +0,0 @@
1
- export { default as SafeAreaView } from './SafeAreaView';
2
- export type { default as SafeAreaViewProps, SafeAreaEdge } from './SafeAreaView.props';
@@ -1 +0,0 @@
1
- export { default as SafeAreaView } from './SafeAreaView';
@@ -1,20 +0,0 @@
1
- import { ViewProps } from 'react-native';
2
-
3
- export type SafeAreaEdge = 'top' | 'right' | 'bottom' | 'left';
4
-
5
- interface SafeAreaViewProps extends ViewProps {
6
- /**
7
- * Which edges should receive safe area compensation.
8
- *
9
- * @default ['top', 'right', 'bottom', 'left']
10
- */
11
- edges?: SafeAreaEdge[];
12
- /**
13
- * Whether safe area compensation should be applied as padding or margin.
14
- *
15
- * @default 'padding'
16
- */
17
- mode?: 'padding' | 'margin';
18
- }
19
-
20
- export default SafeAreaViewProps;