Skip to content

Fix: Sheet background #114

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

Merged
merged 7 commits into from
Jan 18, 2025
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,6 @@ android/generated

# Docs
.vercel

# Misc
.xcode.env.local
40 changes: 29 additions & 11 deletions android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.lodev09.truesheet

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RoundRectShape
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
Expand Down Expand Up @@ -38,6 +40,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
* The maximum window height
*/
var maxScreenHeight = 0

var contentHeight = 0
var footerHeight = 0
var maxSheetHeight: Int? = null
Expand All @@ -57,12 +60,15 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
behavior.isHideable = value
}

var cornerRadius: Float = 0f
var backgroundColor: Int = Color.WHITE
var footerView: ViewGroup? = null

var sizes: Array<Any> = arrayOf("medium", "large")

init {
setContentView(rootSheetView)

sheetView = rootSheetView.parent as ViewGroup
sheetView.setBackgroundColor(Color.TRANSPARENT)

Expand Down Expand Up @@ -93,6 +99,18 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
}
}

/**
* Setup background color and corner radius.
*/
fun setupBackground() {
val outerRadii = FloatArray(8) { cornerRadius }
val background = ShapeDrawable(RoundRectShape(outerRadii, null, null))

// Use current background color
background.paint.color = backgroundColor
sheetView.background = background
}

/**
* Setup dimmed sheet.
* `dimmedIndex` will further customize the dimming behavior.
Expand Down Expand Up @@ -171,11 +189,11 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
* Get the height value based on the size config value.
*/
private fun getSizeHeight(size: Any): Int {
val height =
val height: Int =
when (size) {
is Double -> Utils.toPixel(size)
is Double -> Utils.toPixel(size).toInt()

is Int -> Utils.toPixel(size.toDouble())
is Int -> Utils.toPixel(size.toDouble()).toInt()

is String -> {
when (size) {
Expand All @@ -200,7 +218,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
if (fixedHeight == null) {
0
} else {
Utils.toPixel(fixedHeight)
Utils.toPixel(fixedHeight).toInt()
}
}
}
Expand Down Expand Up @@ -278,7 +296,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
isFitToContents = true

// m3 max width 640dp
maxWidth = Utils.toPixel(640.0)
maxWidth = Utils.toPixel(640.0).toInt()

when (sizes.size) {
1 -> {
Expand Down Expand Up @@ -311,29 +329,29 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
when (sizes.size) {
1 -> {
when (state) {
BottomSheetBehavior.STATE_EXPANDED -> SizeInfo(0, Utils.toDIP(behavior.maxHeight))
BottomSheetBehavior.STATE_EXPANDED -> SizeInfo(0, Utils.toDIP(behavior.maxHeight.toFloat()))
else -> null
}
}

2 -> {
when (state) {
BottomSheetBehavior.STATE_COLLAPSED -> SizeInfo(0, Utils.toDIP(behavior.peekHeight))
BottomSheetBehavior.STATE_EXPANDED -> SizeInfo(1, Utils.toDIP(behavior.maxHeight))
BottomSheetBehavior.STATE_COLLAPSED -> SizeInfo(0, Utils.toDIP(behavior.peekHeight.toFloat()))
BottomSheetBehavior.STATE_EXPANDED -> SizeInfo(1, Utils.toDIP(behavior.maxHeight.toFloat()))
else -> null
}
}

3 -> {
when (state) {
BottomSheetBehavior.STATE_COLLAPSED -> SizeInfo(0, Utils.toDIP(behavior.peekHeight))
BottomSheetBehavior.STATE_COLLAPSED -> SizeInfo(0, Utils.toDIP(behavior.peekHeight.toFloat()))

BottomSheetBehavior.STATE_HALF_EXPANDED -> {
val height = behavior.halfExpandedRatio * maxScreenHeight
SizeInfo(1, Utils.toDIP(height.toInt()))
SizeInfo(1, Utils.toDIP(height))
}

BottomSheetBehavior.STATE_EXPANDED -> SizeInfo(2, Utils.toDIP(behavior.maxHeight))
BottomSheetBehavior.STATE_EXPANDED -> SizeInfo(2, Utils.toDIP(behavior.maxHeight.toFloat()))

else -> null
}
Expand Down
18 changes: 16 additions & 2 deletions android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class TrueSheetView(context: Context) :
/**
* Current activeIndex.
*/
private var currentSizeIndex: Int = 0
private var currentSizeIndex: Int = -1

/**
* Promise callback to be invoked after `present` is called.
Expand Down Expand Up @@ -70,7 +70,7 @@ class TrueSheetView(context: Context) :
// Configure Sheet Dialog
sheetDialog.apply {
setOnSizeChangeListener { w, h ->
eventDispatcher?.dispatchEvent(ContainerSizeChangeEvent(surfaceId, id, Utils.toDIP(w), Utils.toDIP(h)))
eventDispatcher?.dispatchEvent(ContainerSizeChangeEvent(surfaceId, id, Utils.toDIP(w.toFloat()), Utils.toDIP(h.toFloat())))
}

// Setup listener when the dialog has been presented.
Expand Down Expand Up @@ -289,6 +289,20 @@ class TrueSheetView(context: Context) :
}
}

fun setCornerRadius(radius: Float) {
if (sheetDialog.cornerRadius == radius) return

sheetDialog.cornerRadius = radius
sheetDialog.setupBackground()
}

fun setBackground(color: Int) {
if (sheetDialog.backgroundColor == color) return

sheetDialog.backgroundColor = color
sheetDialog.setupBackground()
}

fun setSoftInputMode(mode: Int) {
sheetDialog.window?.apply {
this.setSoftInputMode(mode)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.lodev09.truesheet

import android.graphics.Color
import android.util.Log
import android.view.WindowManager
import com.facebook.react.bridge.ReadableArray
Expand Down Expand Up @@ -41,7 +42,7 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {

@ReactProp(name = "maxHeight")
fun setMaxHeight(view: TrueSheetView, height: Double) {
view.setMaxHeight(Utils.toPixel(height))
view.setMaxHeight(Utils.toPixel(height).toInt())
}

@ReactProp(name = "dismissible")
Expand Down Expand Up @@ -81,12 +82,23 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {

@ReactProp(name = "contentHeight")
fun setContentHeight(view: TrueSheetView, height: Double) {
view.setContentHeight(Utils.toPixel(height))
view.setContentHeight(Utils.toPixel(height).toInt())
}

@ReactProp(name = "footerHeight")
fun setFooterHeight(view: TrueSheetView, height: Double) {
view.setFooterHeight(Utils.toPixel(height))
view.setFooterHeight(Utils.toPixel(height).toInt())
}

@ReactProp(name = "cornerRadius")
fun setCornerRadius(view: TrueSheetView, radius: Double) {
view.setCornerRadius(Utils.toPixel(radius))
}

@ReactProp(name = "background")
fun setBackground(view: TrueSheetView, colorName: String) {
val color = runCatching { Color.parseColor(colorName) }.getOrDefault(Color.WHITE)
view.setBackground(color)
}

@ReactProp(name = "sizes")
Expand Down
27 changes: 10 additions & 17 deletions android/src/main/java/com/lodev09/truesheet/core/RootSheetView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@ import com.facebook.react.views.view.ReactViewGroup
class RootSheetView(private val context: Context?) :
ReactViewGroup(context),
RootView {
private var hasAdjustedSize = false
private var viewWidth = 0
private var viewHeight = 0

private val jSTouchDispatcher = JSTouchDispatcher(this)
private var jSPointerDispatcher: JSPointerDispatcher? = null
public var sizeChangeListener: ((w: Int, h: Int) -> Unit)? = null
var sizeChangeListener: ((w: Int, h: Int) -> Unit)? = null

var eventDispatcher: EventDispatcher? = null

Expand All @@ -43,37 +42,31 @@ class RootSheetView(private val context: Context?) :
}
}

private val reactContext: ThemedReactContext
get() = context as ThemedReactContext

private fun updateContainerSize() {
sizeChangeListener?.let { it(viewWidth, viewHeight) }
}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)

viewWidth = w
viewHeight = h
updateFirstChildView()
}

private fun updateFirstChildView() {
if (childCount > 0) {
hasAdjustedSize = false
sizeChangeListener?.let { it(viewWidth, viewHeight) }
} else {
hasAdjustedSize = true
}
updateContainerSize()
}

override fun addView(child: View, index: Int, params: LayoutParams) {
super.addView(child, index, params)
if (hasAdjustedSize) {
updateFirstChildView()
}
updateContainerSize()
}

override fun handleException(t: Throwable) {
reactContext.reactApplicationContext.handleException(RuntimeException(t))
}

private val reactContext: ThemedReactContext
get() = context as ThemedReactContext

override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
eventDispatcher?.let { jSTouchDispatcher.handleTouchEvent(event, it) }
jSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
Expand Down
4 changes: 2 additions & 2 deletions android/src/main/java/com/lodev09/truesheet/core/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ object Utils {
}
}

fun toDIP(value: Int): Float = PixelUtil.toDIPFromPixel(value.toFloat())
fun toPixel(value: Double): Int = PixelUtil.toPixelFromDIP(value).toInt()
fun toDIP(value: Float): Float = PixelUtil.toDIPFromPixel(value)
fun toPixel(value: Double): Float = PixelUtil.toPixelFromDIP(value)

fun withPromise(promise: Promise, closure: () -> Any?) {
try {
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/reference/01-props.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ The sheet's background color.
| - | - | - | - |
| `ColorValue` | `"white"` | ✅ | ✅ |

:::info
This prop only supports HEX and named colors. Example: `#282e37ff`, `blue`.
:::

### `cornerRadius`

The sheet corner radius.
Expand Down
1 change: 0 additions & 1 deletion example/ios/.xcode.env.local

This file was deleted.

2 changes: 2 additions & 0 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ENV['RCT_NEW_ARCH_ENABLED'] = '1'

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
'require.resolve(
Expand Down
31 changes: 3 additions & 28 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ PODS:
- Yoga
- react-native-maps (1.20.1):
- React-Core
- react-native-true-sheet (0.1.0):
- react-native-true-sheet (1.0.3):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1532,27 +1532,6 @@ PODS:
- React-logger (= 0.76.3)
- React-perflogger (= 0.76.3)
- React-utils (= 0.76.3)
- RNGestureHandler (2.21.2):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNReanimated (3.16.3):
- DoubleConversion
- glog
Expand Down Expand Up @@ -1710,7 +1689,6 @@ DEPENDENCIES:
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
- ReactCodegen (from `build/generated/ios`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)

Expand Down Expand Up @@ -1848,8 +1826,6 @@ EXTERNAL SOURCES:
:path: build/generated/ios
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
Yoga:
Expand Down Expand Up @@ -1892,7 +1868,7 @@ SPEC CHECKSUMS:
React-Mapbuffer: ad1ba0205205a16dbff11b8ade6d1b3959451658
React-microtasksnativemodule: e771eb9eb6ace5884ee40a293a0e14a9d7a4343c
react-native-maps: ee1e65647460c3d41e778071be5eda10e3da6225
react-native-true-sheet: 4a449f0688b0d769ef20c0e21e21d178b8fbd6dd
react-native-true-sheet: 00be9fe24ef77f41f9c70efbeb30bb5ac91c2893
React-nativeconfig: aeed6e2a8ac02b2df54476afcc7c663416c12bf7
React-NativeModulesApple: c5b7813da94136f50ef084fa1ac077332dcfc658
React-perflogger: 6afb7eebf7d9521cc70481688ccddf212970e9d3
Expand Down Expand Up @@ -1920,11 +1896,10 @@ SPEC CHECKSUMS:
React-utils: 2bcaf4f4dfe361344bce2fae428603d518488630
ReactCodegen: ae99a130606068ed40d1d9c0d5f25fda142a0647
ReactCommon: 89c87b343deacc8610b099ac764848f0ce937e3e
RNGestureHandler: 0e5ae8d72ef4afb855e98dcdbe60f27d938abe13
RNReanimated: 006a5d3961bf09c1e96d62ed436e02b2e43b89bb
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: 3deb2471faa9916c8a82dda2a22d3fba2620ad37

PODFILE CHECKSUM: 5eaf14a39e31872a9c12e5d368593ff6b4a71d73
PODFILE CHECKSUM: b38a1c0f527446c0db5a072821b4af1c2506e252

COCOAPODS: 1.16.2
1 change: 1 addition & 0 deletions example/src/sheets/BasicSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const BasicSheet = forwardRef((props: BasicSheetProps, ref: Ref<TrueSheet
blurTint="dark"
backgroundColor={DARK}
cornerRadius={12}
edgeToEdge
grabberProps={{ color: GRABBER_COLOR }}
onDismiss={() => console.log('Basic sheet dismissed!')}
onPresent={({ index, value }) =>
Expand Down
1 change: 1 addition & 0 deletions example/src/sheets/BlankSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const BlankSheet = forwardRef((props: BlankSheetProps, ref: Ref<TrueSheet
sizes={['medium', 'large']}
blurTint="dark"
cornerRadius={12}
edgeToEdge
backgroundColor={DARK}
keyboardMode="pan"
contentContainerStyle={styles.content}
Expand Down
Loading
Loading