Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Margin mode #85

Merged
merged 6 commits into from May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions README.md
Expand Up @@ -18,7 +18,7 @@ or npm:
npm install --save react-native-safe-area-context
```

You then need to link the native parts of the library for the platforms you are using.
You then need to link the native parts of the library for the platforms you are using.

#### Linking in React Native >= 0.60

Expand Down Expand Up @@ -95,9 +95,11 @@ protected List<ReactPackage> getPackages() {

## Usage

`SafeAreaView` is a regular `View` component with the safe area edges applied as padding.
`SafeAreaView` is a regular `View` component with the safe area edges applied as padding - or margins if you prefer.

If you set your own padding on the view, it will be added to the padding from the safe area.
If you set your own padding or margin on the view, it will be added to the padding or margin from the safe area.

For the moment, you can't put paddings or margins as percent values - regardless of where your safe areas are being applied.

**If you are targeting web, you must set up `SafeAreaProvider` in as described in the hooks section**. You do not need to for native platforms.

Expand All @@ -123,6 +125,12 @@ All props are optional.

On iOS 10, emulate the safe area using the status bar height and home indicator sizes.

#### `mode`

`padding` (default) or `margin`

Apply the safe area to either the padding or the margin.

#### `edges`

Array of `top`, `right`, `bottom`, and `left`. Defaults to all.
Expand Down
Expand Up @@ -25,7 +25,7 @@ public SafeAreaProvider(Context context) {
}

private void maybeUpdateInsets() {
EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(getRootView(), this);
EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(getRootView());
Rect frame = SafeAreaUtils.getFrame((ViewGroup) getRootView(), this);
if (edgeInsets != null && frame != null &&
(mLastInsets == null ||
Expand Down
Expand Up @@ -70,7 +70,7 @@ public Map<String, Object> getExportedViewConstants() {
}

View contentView = decorView.findViewById(android.R.id.content);
EdgeInsets insets = SafeAreaUtils.getSafeAreaInsets(decorView, contentView);
EdgeInsets insets = SafeAreaUtils.getSafeAreaInsets(decorView);
Rect frame = SafeAreaUtils.getFrame(decorView, contentView);
if (insets == null || frame == null) {
return null;
Expand Down
Expand Up @@ -36,7 +36,7 @@
}
}

static @Nullable EdgeInsets getSafeAreaInsets(View rootView, View view) {
static @Nullable EdgeInsets getSafeAreaInsets(View rootView) {
EdgeInsets windowInsets = getRootWindowInsetsCompat(rootView);
if (windowInsets == null) {
return null;
Expand All @@ -45,13 +45,11 @@
// Calculate the part of the view that overlaps with window insets.
float windowWidth = rootView.getWidth();
float windowHeight = rootView.getHeight();
Rect visibleRect = new Rect();
view.getGlobalVisibleRect(visibleRect);

windowInsets.top = Math.max(windowInsets.top - visibleRect.top, 0);
windowInsets.left = Math.max(windowInsets.left - visibleRect.left, 0);
windowInsets.bottom = Math.max(visibleRect.top + view.getHeight() + windowInsets.bottom - windowHeight, 0);
windowInsets.right = Math.max(visibleRect.left + view.getWidth() + windowInsets.right - windowWidth, 0);
windowInsets.top = Math.max(windowInsets.top, 0);
windowInsets.left = Math.max(windowInsets.left, 0);
windowInsets.bottom = Math.max(rootView.getHeight() + windowInsets.bottom - windowHeight, 0);
windowInsets.right = Math.max(rootView.getWidth() + windowInsets.right - windowWidth, 0);
return windowInsets;
}

Expand Down
Expand Up @@ -3,6 +3,7 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.ContextWrapper;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;

Expand All @@ -16,6 +17,7 @@

@SuppressLint("ViewConstructor")
public class SafeAreaView extends ReactViewGroup implements ViewTreeObserver.OnGlobalLayoutListener {
private SafeAreaViewMode mMode = SafeAreaViewMode.PADDING;
private @Nullable EdgeInsets mInsets;
private @Nullable EnumSet<SafeAreaViewEdges> mEdges;

Expand All @@ -40,7 +42,7 @@ private void updateInsets() {
? mEdges
: EnumSet.allOf(SafeAreaViewEdges.class);

SafeAreaViewLocalData localData = new SafeAreaViewLocalData(mInsets, edges);
SafeAreaViewLocalData localData = new SafeAreaViewLocalData(mInsets, mMode, edges);

ReactContext reactContext = getReactContext(this);
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
Expand All @@ -50,13 +52,18 @@ private void updateInsets() {
}
}

public void setMode(SafeAreaViewMode mode) {
mMode = mode;
updateInsets();
}

public void setEdges(EnumSet<SafeAreaViewEdges> edges) {
mEdges = edges;
updateInsets();
}

private void maybeUpdateInsets() {
EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(getRootView(), this);
EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(getRootView());
if (edgeInsets != null && (mInsets == null || !mInsets.equalsToEdgeInsets(edgeInsets))) {
mInsets = edgeInsets;
updateInsets();
Expand Down
Expand Up @@ -4,17 +4,23 @@

public class SafeAreaViewLocalData {
private EdgeInsets mInsets;
private SafeAreaViewMode mMode;
private EnumSet<SafeAreaViewEdges> mEdges;

public SafeAreaViewLocalData(EdgeInsets insets, EnumSet<SafeAreaViewEdges> edges) {
public SafeAreaViewLocalData(EdgeInsets insets, SafeAreaViewMode mode, EnumSet<SafeAreaViewEdges> edges) {
mInsets = insets;
mMode = mode;
mEdges = edges;
}

public EdgeInsets getInsets() {
return mInsets;
}

public SafeAreaViewMode getMode() {
return mMode;
}

public EnumSet<SafeAreaViewEdges> getEdges() {
return mEdges;
}
Expand Down
Expand Up @@ -40,6 +40,15 @@ public Class<? extends LayoutShadowNode> getShadowNodeClass() {
return SafeAreaViewShadowNode.class;
}

@ReactProp(name = "mode")
public void setMode(SafeAreaView view, String mode) {
if ("padding".equals(mode)) {
view.setMode(SafeAreaViewMode.PADDING);
} else if ("margin".equals(mode)) {
view.setMode(SafeAreaViewMode.MARGIN);
}
}

@ReactProp(name = "edges")
public void setEdges(SafeAreaView view, @Nullable ReadableArray propList) {
EnumSet<SafeAreaViewEdges> edges = EnumSet.noneOf(SafeAreaViewEdges.class);
Expand Down
@@ -0,0 +1,6 @@
package com.th3rdwave.safeareacontext;

public enum SafeAreaViewMode {
PADDING,
MARGIN
}