Skip to content

Commit 61e5663

Browse files
committed
fix(expo): render auth content in partial sheet
1 parent eb5fb63 commit 61e5663

1 file changed

Lines changed: 73 additions & 7 deletions

File tree

packages/expo/android/src/main/java/expo/modules/clerk/ClerkAuthViewModule.kt

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,30 @@ package expo.modules.clerk
22

33
import android.content.Context
44
import android.util.Log
5+
import androidx.compose.foundation.Canvas
56
import androidx.compose.foundation.isSystemInDarkTheme
67
import androidx.compose.foundation.layout.Box
78
import androidx.compose.foundation.layout.BoxWithConstraints
89
import androidx.compose.foundation.layout.fillMaxSize
910
import androidx.compose.foundation.layout.fillMaxWidth
1011
import androidx.compose.foundation.layout.height
12+
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.layout.size
14+
import androidx.compose.material3.BottomSheetDefaults
1115
import androidx.compose.material3.ExperimentalMaterial3Api
16+
import androidx.compose.material3.IconButton
1217
import androidx.compose.material3.ModalBottomSheet
1318
import androidx.compose.material3.SheetValue
1419
import androidx.compose.material3.rememberModalBottomSheetState
1520
import androidx.compose.runtime.Composable
21+
import androidx.compose.ui.Alignment
1622
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.geometry.Offset
1724
import androidx.compose.ui.graphics.Color
25+
import androidx.compose.ui.graphics.StrokeCap
26+
import androidx.compose.ui.platform.LocalDensity
27+
import androidx.compose.ui.semantics.contentDescription
28+
import androidx.compose.ui.semantics.semantics
1829
import androidx.compose.ui.unit.dp
1930
import androidx.lifecycle.ViewModelStore
2031
import androidx.lifecycle.ViewModelStoreOwner
@@ -89,32 +100,76 @@ class ClerkAuthNativeView(context: Context, appContext: AppContext) : ClerkCompo
89100
onDismissRequest = ::sendDismissEvent,
90101
sheetState = sheetState,
91102
containerColor = clerkBackgroundColor(),
103+
dragHandle = { SheetDragHandle() },
92104
) {
93105
BoxWithConstraints(modifier = Modifier.fillMaxSize()) {
94-
val authHeight =
95-
if (sheetState.currentValue == SheetValue.Expanded) maxHeight else maxHeight / 2
96-
97-
Box(modifier = Modifier.fillMaxWidth().height(authHeight)) {
98-
ClerkAuthView()
106+
val density = LocalDensity.current
107+
val sheetOffsetPx =
108+
runCatching { sheetState.requireOffset() }
109+
.getOrDefault(with(density) { maxHeight.toPx() })
110+
val sheetOffset = with(density) { sheetOffsetPx.toDp() }
111+
val authHeight = (maxHeight - sheetOffset).coerceAtLeast(0.dp)
112+
113+
if (sheetState.currentValue != SheetValue.Hidden) {
114+
Box(modifier = Modifier.fillMaxWidth().height(authHeight)) {
115+
ClerkAuthView(showDismissAction = false)
116+
}
99117
}
100118
}
101119
}
102120
}
103121

104122
@Composable
105-
private fun ClerkAuthView() {
123+
private fun ClerkAuthView(showDismissAction: Boolean = isDismissible) {
106124
AuthView(
107125
modifier = Modifier.fillMaxSize(),
108126
clerkTheme = authTheme(),
109127
mode = authMode(mode),
110-
isDismissible = isDismissible,
128+
isDismissible = showDismissAction,
111129
onDismiss = ::sendDismissEvent,
112130
onAuthComplete = {
113131
sendDismissEvent()
114132
},
115133
)
116134
}
117135

136+
@Composable
137+
@OptIn(ExperimentalMaterial3Api::class)
138+
private fun SheetDragHandle() {
139+
Box(modifier = Modifier.fillMaxWidth().height(48.dp)) {
140+
BottomSheetDefaults.DragHandle(modifier = Modifier.align(Alignment.Center))
141+
if (isDismissible) {
142+
IconButton(
143+
onClick = ::sendDismissEvent,
144+
modifier =
145+
Modifier.align(Alignment.CenterEnd)
146+
.padding(end = 12.dp)
147+
.semantics { contentDescription = "Close" },
148+
) {
149+
val color = clerkForegroundColor()
150+
Canvas(modifier = Modifier.size(24.dp)) {
151+
val inset = 4.dp.toPx()
152+
val strokeWidth = 2.dp.toPx()
153+
drawLine(
154+
color = color,
155+
start = Offset(inset, inset),
156+
end = Offset(size.width - inset, size.height - inset),
157+
strokeWidth = strokeWidth,
158+
cap = StrokeCap.Round,
159+
)
160+
drawLine(
161+
color = color,
162+
start = Offset(size.width - inset, inset),
163+
end = Offset(inset, size.height - inset),
164+
strokeWidth = strokeWidth,
165+
cap = StrokeCap.Round,
166+
)
167+
}
168+
}
169+
}
170+
}
171+
}
172+
118173
@Composable
119174
private fun clerkBackgroundColor(): Color {
120175
val isDarkMode = isSystemInDarkTheme()
@@ -126,6 +181,17 @@ class ClerkAuthNativeView(context: Context, appContext: AppContext) : ClerkCompo
126181
?: if (isDarkMode) Color(0xFF131316) else Color.White
127182
}
128183

184+
@Composable
185+
private fun clerkForegroundColor(): Color {
186+
val isDarkMode = isSystemInDarkTheme()
187+
val customTheme = Clerk.customTheme
188+
val modeColors = if (isDarkMode) customTheme?.darkColors else customTheme?.lightColors
189+
190+
return modeColors?.foreground
191+
?: customTheme?.colors?.foreground
192+
?: if (isDarkMode) Color.White else Color.Black
193+
}
194+
129195
private fun authTheme(): ClerkTheme? {
130196
val maxHeight = logoMaxHeight ?: return Clerk.customTheme
131197
val theme = Clerk.customTheme ?: ClerkTheme()

0 commit comments

Comments
 (0)