react-native-safe-area-context icon indicating copy to clipboard operation
react-native-safe-area-context copied to clipboard

Turn off all edges?

Open duggster opened this issue 3 years ago • 5 comments

I would like to be able to pass an empty array to the edges prop of SafeAreaView when I don't want any safe area edges. The use case is a reusable component that on some screens I want it to take into account Safe Area, and other screens already take Safe Area into account and I don't want double padding. So I'd like to pass a prop to my reusable component that can be used like so:

const MyComponent = ({ needsSafeArea }) => {
  const edges = [];
  if (needsSafeArea) {
    edges.push('top');
  }

  return (<SafeAreaView edges={edges}>
    {/* My cool component */}    
  </SafeAreaView>);
};

This code currently results in all edges being activated when needsSafeArea is false. If there's a better way to handle my use case then please let me know.

duggster avatar Jun 30 '21 20:06 duggster

If you don't need any edges, can you use a View instead?

const MyComponent = ({ needsSafeArea }) => {
  if (needsSafeArea) {
    return (
      <SafeAreaView edges={['top']}>
        {/* My cool component */}    
      </SafeAreaView>
    );
  }

  return (
    <View>
      {/* My cool component */}    
    </View>
  );
};

fiznool avatar Jul 15 '21 21:07 fiznool

Yes this is a workaround, but not great because you either have to duplicate the code inside or create another layer of abstraction by factoring out the common code into yet another component. It would be much more readable and maintainable to just keep the SafeAreaView structure in place and control the behavior by props.

An empty edges array seemed intuitive to indicate no edges at first (before I re-read the docs), but probably it would be less disruptive to existing code if an optional flag was added called something like 'disabled'.

duggster avatar Jul 15 '21 22:07 duggster

I've also come to few use cases where I'd use that passing edges={[]} turns off all edges. It's surprising to me it doesn't, because the code clearly says what I want and that is to use no edges. If it would work like that and you would have opposite condition like "if something is true, I want only top edge, otherwise use default edges" you could still do that by edges={condition? ['top'] : undefined}, so to me it seems like win-win.

Anyway, best workaround I found is to use useSafeAreaInsets

import React from 'react';
import { View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

const MyComponent = ({ needsSafeArea }) => {
 const { top } = useSafeAreaInsets();
 return (
   <View style={{paddingTop: needsSafeArea? top : 0}}>
     {/* My cool component */}    
   </View>
 );
};

CptFabulouso avatar Aug 13 '21 12:08 CptFabulouso

Any news on modifying the bit mask to allow this behaviour? I confirm this would be useful to programmatically change edges while keeping the cool SafeAreaView and not the insets

MaximeCrp avatar Sep 13 '21 12:09 MaximeCrp

useSafeAreaInsets isn't the best solution because it can cause layout flickering (which happens quite commonly in my experience, especially on android). Would really like it if we could pass empty array.

The best work around IMO is to use conditional rendering and contain the SafeAreaView within the regular view.

<View>
    {topInsets &&
        <SafeAreaView edges={['top']}/>
    }
    {bottomInsets &&
        <SafeAreaView edges={['bottom']}/>
    }
</View>

iway1 avatar Mar 07 '22 15:03 iway1

I also vote for this dev-friendly feature!

Nesh108 avatar Oct 25 '22 10:10 Nesh108

Yeah, this is an odd one. The default is all edges seen here. You could change this to 0 to mean no edges - then you'd need to update this to default to passing in all edges if the edges prop isn't provided

jacobp100 avatar Jan 19 '23 11:01 jacobp100

Is this planned on the roadmap? Or could we help by creating a PR?

VNDRN avatar Apr 25 '23 09:04 VNDRN

If someone raised a PR for this, we'd merge it. I think it literally is as simple as changing the line I highlighted from RNCSafeAreaViewEdgesAll to 0

The edges get set to their default here

jacobp100 avatar Apr 25 '23 09:04 jacobp100

Would setting that to 0 not change the default to no edges? I think it should still default to all edges, just when passing an empty array, it should use no edges?

VNDRN avatar Apr 25 '23 09:04 VNDRN

@VNDRN

The edges get set to their default here

jacobp100 avatar Apr 25 '23 09:04 jacobp100

@jacobp100 , I've implemented it for iOS, not sure if android needs to be looked at as well, I couldn't find a device to test it on

VNDRN avatar Apr 25 '23 12:04 VNDRN

https://github.com/th3rdwave/react-native-safe-area-context/pull/378

jacobp100 avatar May 09 '23 20:05 jacobp100