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

feat: add initialIndex & onMount props #30

Merged
merged 18 commits into from
Jun 10, 2024
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: 1 addition & 2 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ nmHoistingLimits: workspaces
nodeLinker: node-modules

plugins:
spec: "@yarnpkg/plugin-interactive-tools"
spec: "@yarnpkg/plugin-workspace-tools"
spec: "@yarnpkg/plugin-workspace-tools"
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

The true native bottom sheet experience for your React Native Apps. 💩

<img alt="React Native True Sheet" src="docs/static/img/preview.gif" width="600px" />
<img alt="React Native True Sheet - IOS" src="docs/static/img/preview.gif" width="300" height="600" />
<img alt="React Native True Sheet - Android" src="docs/static/img/preview-2.gif" width="300" height="600" />

## Features

Expand Down
38 changes: 27 additions & 11 deletions android/src/main/java/com/lodev09/truesheet/TrueSheetDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
BottomSheetDialog(reactContext) {

private var keyboardManager = KeyboardManager(reactContext)
private var sheetView: ViewGroup
private var windowAnimation: Int = 0

/**
* Specify whether the sheet background is dimmed.
Expand Down Expand Up @@ -53,19 +55,20 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val

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

private var sheetView: ViewGroup

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

// Setup window params to adjust layout based on Keyboard state.
// Setup window params to adjust layout based on Keyboard state
window?.apply {
// SOFT_INPUT_ADJUST_RESIZE to resize the sheet above the keyboard
setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
)

// Store current windowAnimation value to toggle later
windowAnimation = attributes.windowAnimations
}

// Update the usable sheet height
Expand Down Expand Up @@ -107,18 +110,29 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
}
}

fun resetAnimation() {
window?.apply {
setWindowAnimations(windowAnimation)
}
}

/**
* Present the sheet.
*/
fun present(sizeIndex: Int) {
fun present(sizeIndex: Int, animated: Boolean = true) {
setupDimmedBackground(sizeIndex)
if (isShowing) {
setStateForSizeIndex(sizeIndex)
} else {
configure()
setStateForSizeIndex(sizeIndex)

this.show()
if (!animated) {
// Disable animation
window?.setWindowAnimations(0)
}

show()
}
}

Expand Down Expand Up @@ -178,10 +192,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
else -> (maxScreenHeight * 0.5).toInt()
}

return when (maxSheetHeight) {
null -> height
else -> minOf(height, maxSheetHeight ?: maxScreenHeight)
}
return maxSheetHeight?.let { minOf(height, it, maxScreenHeight) } ?: minOf(height, maxScreenHeight)
}

/**
Expand Down Expand Up @@ -216,7 +227,7 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
* Also update footer's Y position.
*/
fun registerKeyboardManager() {
keyboardManager.registerKeyboardListener(object : KeyboardManager.OnKeyboardListener {
keyboardManager.registerKeyboardListener(object : KeyboardManager.OnKeyboardChangeListener {
override fun onKeyboardStateChange(isVisible: Boolean, visibleHeight: Int?) {
maxScreenHeight = when (isVisible) {
true -> visibleHeight ?: 0
Expand All @@ -228,6 +239,10 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
})
}

fun setOnSizeChangeListener(listener: RootSheetView.OnSizeChangeListener) {
rootSheetView.setOnSizeChangeListener(listener)
}

/**
* Remove keyboard listener.
*/
Expand Down Expand Up @@ -263,7 +278,8 @@ class TrueSheetDialog(private val reactContext: ThemedReactContext, private val
isFitToContents = false

setPeekHeight(getSizeHeight(sizes[0]), isShowing)
halfExpandedRatio = getSizeHeight(sizes[1]).toFloat() / maxScreenHeight.toFloat()

halfExpandedRatio = minOf(getSizeHeight(sizes[1]).toFloat() / maxScreenHeight.toFloat(), 1.0f)
maxHeight = getSizeHeight(sizes[2])
}
}
Expand Down
66 changes: 50 additions & 16 deletions android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.events.EventDispatcher
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.lodev09.truesheet.core.DismissEvent
import com.lodev09.truesheet.core.PresentEvent
import com.lodev09.truesheet.core.RootSheetView
import com.lodev09.truesheet.core.SizeChangeEvent
import com.lodev09.truesheet.events.DismissEvent
import com.lodev09.truesheet.events.MountEvent
import com.lodev09.truesheet.events.PresentEvent
import com.lodev09.truesheet.events.SizeChangeEvent

class TrueSheetView(context: Context) :
ViewGroup(context),
Expand All @@ -27,6 +28,9 @@ class TrueSheetView(context: Context) :
private val surfaceId: Int
get() = UIManagerHelper.getSurfaceId(this)

var initialIndex: Int = -1
var initialIndexAnimated: Boolean = true

/**
* Current activeIndex.
*/
Expand All @@ -52,11 +56,6 @@ class TrueSheetView(context: Context) :
*/
private val rootSheetView: RootSheetView

/**
* 2nd child of the container view.
*/
private var footerView: ViewGroup? = null

init {
reactContext.addLifecycleEventListener(this)
eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
Expand All @@ -77,13 +76,16 @@ class TrueSheetView(context: Context) :
positionFooter()
}

// Re-enable animation
resetAnimation()

// Resolve the present promise
presentPromise?.let { promise ->
promise()
presentPromise = null
}

// dispatch onPresent event
// Dispatch onPresent event
eventDispatcher?.dispatchEvent(PresentEvent(surfaceId, id, sheetDialog.getSizeInfoForIndex(currentSizeIndex)))
}

Expand All @@ -97,10 +99,17 @@ class TrueSheetView(context: Context) :
dismissPromise = null
}

// dispatch onDismiss event
// Dispatch onDismiss event
eventDispatcher?.dispatchEvent(DismissEvent(surfaceId, id))
}

// Configure when showing and size changed
setOnSizeChangeListener(object : RootSheetView.OnSizeChangeListener {
override fun onSizeChange(width: Int, height: Int) {
maxScreenHeight = height
}
})

// Configure sheet behavior events
behavior.addBottomSheetCallback(
object : BottomSheetBehavior.BottomSheetCallback() {
Expand Down Expand Up @@ -132,7 +141,7 @@ class TrueSheetView(context: Context) :
currentSizeIndex = sizeInfo.index
setupDimmedBackground(sizeInfo.index)

// dispatch onSizeChange event
// Dispatch onSizeChange event
eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
}
}
Expand Down Expand Up @@ -164,13 +173,28 @@ class TrueSheetView(context: Context) :
visibility = GONE

(child as ViewGroup).let {
// Container View's first child is the Content View
footerView = it.getChildAt(1) as ViewGroup

sheetDialog.footerView = footerView

// rootView's first child is the Container View
rootSheetView.addView(it, index)

// Initialize content
UiThreadUtil.runOnUiThread {
// 1st child is the content view
val contentView = it.getChildAt(0) as ViewGroup
setContentHeight(contentView.height)

// 2nd child is the footer view
val footerView = it.getChildAt(1) as ViewGroup
sheetDialog.footerView = footerView
setFooterHeight(footerView.height)

if (initialIndex >= 0) {
currentSizeIndex = initialIndex
sheetDialog.present(initialIndex, initialIndexAnimated)
}

// Dispatch onMount event
eventDispatcher?.dispatchEvent(MountEvent(surfaceId, id))
}
}
}

Expand Down Expand Up @@ -224,28 +248,38 @@ class TrueSheetView(context: Context) :
}

fun setMaxHeight(height: Int) {
if (sheetDialog.maxSheetHeight == height) return

sheetDialog.maxSheetHeight = height
configureIfShowing()
}

fun setContentHeight(height: Int) {
if (sheetDialog.contentHeight == height) return

sheetDialog.contentHeight = height
configureIfShowing()
}

fun setFooterHeight(height: Int) {
if (sheetDialog.footerHeight == height) return

sheetDialog.footerHeight = height
configureIfShowing()
}

fun setDimmed(dimmed: Boolean) {
if (sheetDialog.dimmed == dimmed) return

sheetDialog.dimmed = dimmed
if (sheetDialog.isShowing) {
sheetDialog.setupDimmedBackground(currentSizeIndex)
}
}

fun setDimmedIndex(index: Int) {
if (sheetDialog.dimmedIndex == index) return

sheetDialog.dimmedIndex = index
if (sheetDialog.isShowing) {
sheetDialog.setupDimmedBackground(currentSizeIndex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import com.facebook.react.common.MapBuilder
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.ViewGroupManager
import com.facebook.react.uimanager.annotations.ReactProp
import com.lodev09.truesheet.core.DismissEvent
import com.lodev09.truesheet.core.PresentEvent
import com.lodev09.truesheet.core.SizeChangeEvent
import com.lodev09.truesheet.core.Utils
import com.lodev09.truesheet.events.DismissEvent
import com.lodev09.truesheet.events.MountEvent
import com.lodev09.truesheet.events.PresentEvent
import com.lodev09.truesheet.events.SizeChangeEvent

class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
override fun getName() = TAG
Expand All @@ -24,6 +25,7 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {

override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any>? =
MapBuilder.builder<String, Any>()
.put(MountEvent.EVENT_NAME, MapBuilder.of("registrationName", "onMount"))
.put(PresentEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPresent"))
.put(DismissEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDismiss"))
.put(SizeChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onSizeChange"))
Expand All @@ -44,6 +46,16 @@ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
view.setDimmed(dimmed)
}

@ReactProp(name = "initialIndex")
lodev09 marked this conversation as resolved.
Show resolved Hide resolved
fun setInitialIndex(view: TrueSheetView, index: Int) {
view.initialIndex = index
}

@ReactProp(name = "initialIndexAnimated")
lodev09 marked this conversation as resolved.
Show resolved Hide resolved
fun setInitialIndexAnimated(view: TrueSheetView, animate: Boolean) {
view.initialIndexAnimated = animate
}

@ReactProp(name = "dimmedIndex")
fun setDimmedIndex(view: TrueSheetView, index: Int) {
view.setDimmedIndex(index)
Expand Down
51 changes: 0 additions & 51 deletions android/src/main/java/com/lodev09/truesheet/core/Events.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import android.view.inputmethod.InputMethodManager
import com.facebook.react.bridge.ReactContext

class KeyboardManager(reactContext: ReactContext) {
interface OnKeyboardListener {
interface OnKeyboardChangeListener {
fun onKeyboardStateChange(isVisible: Boolean, visibleHeight: Int?)
}

Expand All @@ -20,7 +20,7 @@ class KeyboardManager(reactContext: ReactContext) {
contentView = activity?.findViewById(android.R.id.content)
}

fun registerKeyboardListener(listener: OnKeyboardListener?) {
fun registerKeyboardListener(listener: OnKeyboardChangeListener?) {
contentView?.apply {
unregisterKeyboardListener()

Expand Down
Loading