@@ -4,36 +4,33 @@ import androidx.compose.animation.core.Spring
44import androidx.compose.animation.core.animateIntAsState
55import androidx.compose.animation.core.spring
66import androidx.compose.foundation.background
7- import androidx.compose.foundation.clickable
87import androidx.compose.foundation.gestures.Orientation
98import androidx.compose.foundation.layout.Arrangement
109import androidx.compose.foundation.layout.Box
1110import androidx.compose.foundation.layout.BoxWithConstraints
1211import androidx.compose.foundation.layout.Column
12+ import androidx.compose.foundation.layout.ColumnScope
1313import androidx.compose.foundation.layout.Row
1414import androidx.compose.foundation.layout.fillMaxWidth
1515import androidx.compose.foundation.layout.offset
1616import androidx.compose.foundation.layout.padding
17- import androidx.compose.foundation.layout.requiredHeight
1817import androidx.compose.foundation.layout.requiredSize
1918import androidx.compose.foundation.layout.size
2019import androidx.compose.foundation.shape.RoundedCornerShape
21- import androidx.compose.material.Card
2220import androidx.compose.material.DrawerValue
2321import androidx.compose.material.ExperimentalMaterialApi
2422import androidx.compose.material.FractionalThreshold
2523import androidx.compose.material.Icon
2624import androidx.compose.material.IconButton
27- import androidx.compose.material.LocalElevationOverlay
2825import androidx.compose.material.MaterialTheme
26+ import androidx.compose.material.Surface
2927import androidx.compose.material.SwipeableDefaults
3028import androidx.compose.material.SwipeableDefaults.resistanceConfig
3129import androidx.compose.material.SwipeableState
3230import androidx.compose.material.Text
3331import androidx.compose.material.rememberSwipeableState
3432import androidx.compose.material.swipeable
3533import androidx.compose.runtime.Composable
36- import androidx.compose.runtime.CompositionLocalProvider
3734import androidx.compose.runtime.LaunchedEffect
3835import androidx.compose.runtime.derivedStateOf
3936import androidx.compose.runtime.getValue
@@ -101,53 +98,76 @@ fun AppDrawer(
10198 initialDrawerValue : DrawerValue = DrawerValue .Closed ,
10299 onClick : () -> Unit
103100) {
104- val height = dimensionResource(id = R .dimen.app_drawer_height)
101+ val coroutineScope = rememberCoroutineScope()
102+ val swipeableState = rememberSwipeableState(
103+ initialValue = initialDrawerValue,
104+ animationSpec = spring(dampingRatio = 0.6f , stiffness = 1000f )
105+ )
106+ val collapsed by remember {
107+ derivedStateOf {
108+ swipeableState.targetValue == DrawerValue .Closed
109+ }
110+ }
111+
112+ AppDrawerColumn (swipeableState = swipeableState) {
113+ AppDrawerContent (
114+ iconUrl = iconUrl,
115+ caption = caption,
116+ distance = distance,
117+ headline = headline,
118+ isExpanded = ! collapsed,
119+ iconBackgroundColor = iconBackgroundColor,
120+ backgroundColor = backgroundColor,
121+ textColor = textColor,
122+ onClose = {
123+ coroutineScope.launch {
124+ swipeableState.animateTo(DrawerValue .Closed )
125+ }
126+ },
127+ onClick = {
128+ if (collapsed) {
129+ coroutineScope.launch {
130+ swipeableState.animateTo(DrawerValue .Open )
131+ }
132+ } else {
133+ onClick()
134+ }
135+ }
136+ )
137+ }
138+ }
105139
140+ @OptIn(ExperimentalMaterialApi ::class )
141+ @Composable
142+ fun AppDrawerColumn (
143+ modifier : Modifier = Modifier ,
144+ collapsedWidth : Dp = dimensionResource(id = R .dimen.app_drawer_height),
145+ swipeableState : SwipeableState <DrawerValue > = rememberSwipeableState(
146+ initialValue = DrawerValue .Closed ,
147+ animationSpec = spring(dampingRatio = 0.6f, stiffness = 1000f)
148+ ),
149+ content : @Composable ColumnScope .() -> Unit
150+ ) {
106151 BoxWithConstraints (
107- modifier = Modifier
152+ modifier = modifier
108153 .padding(start = 20 .dp)
109- .fillMaxWidth()
110- .requiredHeight(height),
154+ .fillMaxWidth(),
111155 contentAlignment = Alignment .CenterEnd
112156 ) {
113- // Disable elevation overlay in Card so that the background color is not lighter
114- CompositionLocalProvider (LocalElevationOverlay provides null ) {
115- val coroutineScope = rememberCoroutineScope()
116- val iconBoxSizePx = with (LocalDensity .current) { height.toPx() }
117- val collapsedOffset = constraints.maxWidth - iconBoxSizePx
118- val swipeableState = rememberSwipeableState(
119- initialValue = initialDrawerValue,
120- animationSpec = spring(dampingRatio = 0.6f , stiffness = 1000f )
121- )
122- val collapsed by remember {
123- derivedStateOf {
124- swipeableState.targetValue == DrawerValue .Closed
125- }
126- }
157+ val collapsedWidthPx = with (LocalDensity .current) { collapsedWidth.toPx() }
158+ val collapsedOffset = constraints.maxWidth - collapsedWidthPx
127159
128- AppDrawerContent (
129- modifier = Modifier .appDrawer(
130- swipeableState = swipeableState,
131- collapsedOffset = collapsedOffset,
132- onClick = onClick
133- ),
134- iconUrl = iconUrl,
135- caption = caption,
136- distance = distance,
137- headline = headline,
138- isExpanded = ! collapsed,
139- iconBackgroundColor = iconBackgroundColor,
140- backgroundColor = backgroundColor,
141- textColor = textColor
142- ) {
143- coroutineScope.launch {
144- swipeableState.animateTo(DrawerValue .Closed )
145- }
146- }
147- }
160+ Column (
161+ modifier = Modifier .appDrawer(
162+ swipeableState = swipeableState,
163+ collapsedOffset = collapsedOffset
164+ ),
165+ content = content
166+ )
148167 }
149168}
150169
170+ @OptIn(ExperimentalMaterialApi ::class )
151171@Composable
152172fun AppDrawerContent (
153173 modifier : Modifier = Modifier ,
@@ -160,19 +180,21 @@ fun AppDrawerContent(
160180 iconBackgroundColor : Color ? = null,
161181 backgroundColor : Color ? = null,
162182 textColor : Color ? = null,
163- onClose : () -> Unit
183+ onClose : () -> Unit ,
184+ onClick : () -> Unit
164185) {
165186 val drawerIconBackgroundColor = iconBackgroundColor ? : Title
166187 val drawerBackgroundColor = backgroundColor ? : PACEBlue
167188 val drawerTextColor = textColor ? : Title
168189
169- Card (
190+ Surface (
191+ onClick = onClick,
170192 modifier = modifier,
171193 shape = RoundedCornerShape (
172194 topStartPercent = 50 ,
173195 bottomStartPercent = 50
174196 ),
175- backgroundColor = drawerBackgroundColor,
197+ color = drawerBackgroundColor,
176198 elevation = 10 .dp
177199 ) {
178200 Row (verticalAlignment = Alignment .CenterVertically ) {
@@ -331,16 +353,10 @@ fun AppDrawerCloseButton(
331353@Composable
332354fun Modifier.appDrawer (
333355 swipeableState : SwipeableState <DrawerValue >,
334- collapsedOffset : Float ,
335- onClick : () -> Unit
356+ collapsedOffset : Float
336357): Modifier {
337358 val coroutineScope = rememberCoroutineScope()
338359 val anchors = mapOf (0f to DrawerValue .Open , collapsedOffset to DrawerValue .Closed )
339- val collapsed by remember {
340- derivedStateOf {
341- swipeableState.targetValue == DrawerValue .Closed
342- }
343- }
344360
345361 LaunchedEffect (Unit ) {
346362 coroutineScope.launch {
@@ -366,15 +382,6 @@ fun Modifier.appDrawer(
366382 factorAtMax = SwipeableDefaults .StandardResistanceFactor
367383 )
368384 )
369- .clickable {
370- if (collapsed) {
371- coroutineScope.launch {
372- swipeableState.animateTo(DrawerValue .Open )
373- }
374- } else {
375- onClick()
376- }
377- }
378385}
379386
380387@Preview(showBackground = true )
0 commit comments