Ingen beskrivning

index.tsx 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import * as React from 'react';
  2. import { StyleSheet, View, ViewProps } from 'react-native';
  3. import { EdgeInsets, InsetChangedEvent } from './SafeArea.types';
  4. import NativeSafeAreaView from './NativeSafeAreaView';
  5. export const SafeAreaContext = React.createContext<EdgeInsets | null>(null);
  6. export interface SafeAreaViewProps {
  7. children?: React.ReactNode;
  8. }
  9. export function SafeAreaProvider({ children }: SafeAreaViewProps) {
  10. let parentInsets = useParentSafeArea();
  11. const [insets, setInsets] = React.useState<EdgeInsets | null>(null);
  12. const onInsetsChange = React.useCallback((event: InsetChangedEvent) => {
  13. setInsets(event.nativeEvent.insets);
  14. }, []);
  15. // If a provider is nested inside of another provider then we can just use
  16. // the parent insets, without rendering another native safe area view
  17. if (parentInsets) {
  18. return <View style={styles.fill}>{children}</View>;
  19. } else {
  20. return (
  21. <NativeSafeAreaView style={styles.fill} onInsetsChange={onInsetsChange}>
  22. {insets !== null ? (
  23. <SafeAreaContext.Provider value={insets}>
  24. {children}
  25. </SafeAreaContext.Provider>
  26. ) : null}
  27. </NativeSafeAreaView>
  28. );
  29. }
  30. }
  31. const styles = StyleSheet.create({
  32. fill: { flex: 1 },
  33. });
  34. export const SafeAreaConsumer = SafeAreaContext.Consumer;
  35. function useParentSafeArea(): React.ContextType<typeof SafeAreaContext> {
  36. return React.useContext(SafeAreaContext);
  37. }
  38. export function useSafeArea(): EdgeInsets {
  39. const safeArea = React.useContext(SafeAreaContext);
  40. if (safeArea == null) {
  41. throw new Error(
  42. 'No safe area value available. Make sure you are rendering `<SafeAreaProvider>` at the top of your app.',
  43. );
  44. }
  45. return safeArea;
  46. }
  47. export function SafeAreaView({
  48. style,
  49. ...rest
  50. }: ViewProps & { children: React.ReactNode }) {
  51. const insets = useSafeArea();
  52. return (
  53. <View
  54. style={[
  55. {
  56. paddingTop: insets.top,
  57. paddingRight: insets.right,
  58. paddingBottom: insets.bottom,
  59. paddingLeft: insets.left,
  60. },
  61. style,
  62. ]}
  63. {...rest}
  64. />
  65. );
  66. }
  67. export type EdgeInsets = EdgeInsets;