diff --git a/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt b/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt index f47e0ae..9e79819 100644 --- a/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt +++ b/android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt @@ -42,6 +42,12 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val var footerHeight = 0 var maxSheetHeight: Int? = null + var edgeToEdge: Boolean = false + set(value) { + field = value + maxScreenHeight = Utils.screenHeight(reactContext, value) + } + var dismissible: Boolean = true set(value) { field = value @@ -67,7 +73,26 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val } // Update the usable sheet height - maxScreenHeight = Utils.screenHeight(reactContext) + maxScreenHeight = Utils.screenHeight(reactContext, edgeToEdge) + } + + override fun getEdgeToEdgeEnabled(): Boolean { + return edgeToEdge || super.getEdgeToEdgeEnabled() + } + + override fun onStart() { + super.onStart() + + if (edgeToEdge) { + window?.apply { + setFlags( + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + ) + + decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + } + } } /** @@ -226,7 +251,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val override fun onKeyboardStateChange(isVisible: Boolean, visibleHeight: Int?) { maxScreenHeight = when (isVisible) { true -> visibleHeight ?: 0 - else -> Utils.screenHeight(reactContext) + else -> Utils.screenHeight(reactContext, edgeToEdge) } positionFooter() diff --git a/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt b/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt index 01f899f..1d99524 100644 --- a/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +++ b/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt @@ -240,6 +240,10 @@ class TrueSheetView(context: Context) : } } + fun setEdgeToEdge(edgeToEdge: Boolean) { + sheetDialog.edgeToEdge = edgeToEdge + } + fun setMaxHeight(height: Int) { if (sheetDialog.maxSheetHeight == height) return diff --git a/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt b/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt index 573c047..a02b5ba 100644 --- a/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +++ b/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt @@ -32,6 +32,11 @@ class TrueSheetViewManager : ViewGroupManager() { .put(SizeChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onSizeChange")) .build() + @ReactProp(name = "edgeToEdge") + fun setEdgeToEdge(view: TrueSheetView, edgeToEdge: Boolean) { + view.setEdgeToEdge(edgeToEdge) + } + @ReactProp(name = "maxHeight") fun setMaxHeight(view: TrueSheetView, height: Double) { view.setMaxHeight(Utils.toPixel(height)) diff --git a/android/src/main/java/com/lodev09/truesheet/core/Utils.kt b/android/src/main/java/com/lodev09/truesheet/core/Utils.kt index f5f5d71..684ab4e 100644 --- a/android/src/main/java/com/lodev09/truesheet/core/Utils.kt +++ b/android/src/main/java/com/lodev09/truesheet/core/Utils.kt @@ -18,7 +18,7 @@ object Utils { ).takeIf { it > 0 } ?: 0 @SuppressLint("InternalInsetResource", "DiscouragedApi") - fun screenHeight(context: ReactContext): Int { + fun screenHeight(context: ReactContext, edgeToEdge: Boolean): Int { val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager val displayMetrics = DisplayMetrics() @@ -45,7 +45,16 @@ object Utils { 0 } - return screenHeight - statusBarHeight - navigationBarHeight + return if (edgeToEdge) { + // getRealMetrics includes navigation bar height + // windowManager.defaultDisplay.getMetrics doesn't + when (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + true -> screenHeight + false -> screenHeight + navigationBarHeight + } + } else { + screenHeight - statusBarHeight - navigationBarHeight + } } fun toDIP(value: Int): Float = PixelUtil.toDIPFromPixel(value.toFloat()) diff --git a/package.json b/package.json index c1b74e2..44fe632 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,9 @@ "publishConfig": { "registry": "https://registry.npmjs.org/" }, + "dependencies": { + "react-native-is-edge-to-edge": "^1.1.6" + }, "devDependencies": { "@commitlint/config-conventional": "^19.0.3", "@evilmartians/lefthook": "^1.6.5", @@ -139,7 +142,8 @@ "prettier" ], "globals": { - "it": false + "it": false, + "__DEV__": true }, "rules": { "@typescript-eslint/no-var-requires": 0, diff --git a/src/TrueSheet.tsx b/src/TrueSheet.tsx index aadc8a5..211706d 100644 --- a/src/TrueSheet.tsx +++ b/src/TrueSheet.tsx @@ -9,6 +9,7 @@ import { type NativeSyntheticEvent, type LayoutChangeEvent, } from 'react-native' +import { isEdgeToEdge, controlEdgeToEdgeValues } from 'react-native-is-edge-to-edge' import type { TrueSheetProps, SizeInfo } from './TrueSheet.types' import { TrueSheetModule } from './TrueSheetModule' @@ -22,6 +23,8 @@ const LINKING_ERROR = '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n' +const EDGE_TO_EDGE = isEdgeToEdge() + interface TrueSheetNativeViewProps extends Omit { contentHeight?: number footerHeight?: number @@ -194,6 +197,10 @@ export class TrueSheet extends PureComponent { ) } + if (__DEV__) { + controlEdgeToEdgeValues({ edgeToEdge: this.props.edgeToEdge }) + } + this.updateState() } @@ -209,6 +216,7 @@ export class TrueSheet extends PureComponent { grabber = true, dimmed = true, initialIndexAnimated = true, + edgeToEdge = false, keyboardMode = 'resize', initialIndex, dimmedIndex, @@ -236,6 +244,7 @@ export class TrueSheet extends PureComponent { grabber={grabber} dimmed={dimmed} dimmedIndex={dimmedIndex} + edgeToEdge={EDGE_TO_EDGE || edgeToEdge} initialIndex={initialIndex} initialIndexAnimated={initialIndexAnimated} keyboardMode={keyboardMode} diff --git a/src/TrueSheet.types.ts b/src/TrueSheet.types.ts index 486d5f1..160a932 100644 --- a/src/TrueSheet.types.ts +++ b/src/TrueSheet.types.ts @@ -230,6 +230,15 @@ export interface TrueSheetProps extends ViewProps { */ keyboardMode?: 'resize' | 'pan' + /** + * Determines how the software keyboard will impact the layout of the sheet. + * Set to `pan` if you're working with `FlatList` with a `TextInput`. + * + * @platform android + * @default `true` is `react-native-edge-to-edge` is installed, `false` otherwise + */ + edgeToEdge?: boolean + /** * This is called when the sheet is ready to present. */ diff --git a/yarn.lock b/yarn.lock index 9fdc05a..853e8dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3672,6 +3672,7 @@ __metadata: react: "npm:^18.2.0" react-native: "npm:^0.74.1" react-native-builder-bob: "npm:^0.23.2" + react-native-is-edge-to-edge: "npm:^1.1.6" release-it: "npm:^17.1.1" typescript: "npm:~5.3.3" peerDependencies: @@ -18329,6 +18330,16 @@ __metadata: languageName: node linkType: hard +"react-native-is-edge-to-edge@npm:^1.1.6": + version: 1.1.6 + resolution: "react-native-is-edge-to-edge@npm:1.1.6" + peerDependencies: + react: ">=18.2.0" + react-native: ">=0.73.0" + checksum: 10c0/5690e521e8310d21643634a8d0dacd524e19b76695f347b26f649fcac156a7a901fd6daef7f78482381a41e8445f4552f40ade13790fdf112fab15b0f54dbabd + languageName: node + linkType: hard + "react-native-maps@npm:1.14.0": version: 1.14.0 resolution: "react-native-maps@npm:1.14.0"