@@ -30,14 +30,20 @@ import androidx.compose.animation.slideOutVertically
3030import androidx.compose.foundation.layout.Arrangement
3131import androidx.compose.foundation.layout.Box
3232import androidx.compose.foundation.layout.Column
33+ import androidx.compose.foundation.layout.Row
3334import androidx.compose.foundation.layout.padding
35+ import androidx.compose.foundation.layout.widthIn
3436import androidx.compose.foundation.shape.CornerSize
37+ import androidx.compose.material.Card
38+ import androidx.compose.material.ContentAlpha
3539import androidx.compose.material.ExperimentalMaterialApi
3640import androidx.compose.material.FloatingActionButton
3741import androidx.compose.material.FloatingActionButtonDefaults
3842import androidx.compose.material.FloatingActionButtonElevation
3943import androidx.compose.material.Icon
44+ import androidx.compose.material.LocalContentAlpha
4045import androidx.compose.material.MaterialTheme
46+ import androidx.compose.material.ProvideTextStyle
4147import androidx.compose.material.Text
4248import androidx.compose.material.contentColorFor
4349import androidx.compose.material.icons.Icons
@@ -46,16 +52,19 @@ import androidx.compose.material.icons.filled.Close
4652import androidx.compose.material.icons.filled.Search
4753import androidx.compose.material.icons.filled.Share
4854import androidx.compose.runtime.Composable
55+ import androidx.compose.runtime.CompositionLocalProvider
4956import androidx.compose.runtime.getValue
5057import androidx.compose.ui.Alignment
5158import androidx.compose.ui.Modifier
5259import androidx.compose.ui.draw.rotate
5360import androidx.compose.ui.graphics.Color
5461import androidx.compose.ui.graphics.Shape
5562import androidx.compose.ui.tooling.preview.Preview
63+ import androidx.compose.ui.unit.Dp
5664import androidx.compose.ui.unit.IntOffset
5765import androidx.compose.ui.unit.dp
5866
67+ @ExperimentalMaterialApi
5968@ExperimentalAnimationApi
6069@Composable
6170fun SpeedDial (
@@ -72,6 +81,10 @@ fun SpeedDial(
7281 fabOpenedContent : @Composable () -> Unit = { Icon (Icons .Default .Close , null) },
7382 fabOpenedBackgroundColor : Color = MaterialTheme .colors.secondary,
7483 fabOpenedContentColor : Color = contentColorFor(fabOpenedBackgroundColor),
84+ labelContent : @Composable (() -> Unit )? = null,
85+ labelBackgroundColor : Color = MaterialTheme .colors.surface,
86+ labelMaxWidth : Dp = 160.dp,
87+ labelContainerElevation : Dp = 2.dp,
7588 reverseAnimationOnClose : Boolean = false,
7689 contentAnimationDelayInMillis : Int = 20,
7790 content : SpeedDialScope .() -> Unit = {},
@@ -109,41 +122,75 @@ fun SpeedDial(
109122 }
110123 }
111124
112- // Main FAB
113- val fabModifier = Modifier
114- .padding(top = 8 .dp)
115- .rotate(rotation)
116-
117- when (state) {
118- SpeedDialState .Expanded -> FloatingActionButton (
119- onClick = { onFabClick(true ) },
120- modifier = fabModifier,
121- shape = fabShape,
122- backgroundColor = fabOpenedBackgroundColor,
123- contentColor = fabOpenedContentColor,
124- elevation = fabElevation,
125- content = {
125+ Row (
126+ modifier = Modifier .padding(top = 8 .dp),
127+ horizontalArrangement = Arrangement .spacedBy(16 .dp),
128+ verticalAlignment = Alignment .CenterVertically ,
129+ ) {
130+ AnimatedVisibility (
131+ visible = labelContent != null && state.isExpanded(),
132+ enter = fadeIn(),
133+ exit = fadeOut(),
134+ ) {
135+ Card (
136+ modifier = Modifier .widthIn(max = labelMaxWidth),
137+ onClick = { onFabClick(state.isExpanded()) },
138+ backgroundColor = labelBackgroundColor,
139+ elevation = labelContainerElevation,
140+ ) {
126141 Box (
127- modifier = Modifier .rotate( - fabAnimationRotateAngle ),
142+ modifier = Modifier .padding(horizontal = 8 .dp, vertical = 4 .dp ),
128143 propagateMinConstraints = true ,
129144 ) {
130- fabOpenedContent()
145+ ProvideTextStyle (value = MaterialTheme .typography.subtitle2) {
146+ CompositionLocalProvider (
147+ LocalContentAlpha provides ContentAlpha .high,
148+ content = checkNotNull(labelContent),
149+ )
150+ }
131151 }
132- },
133- )
134- SpeedDialState .Collapsed -> FloatingActionButton (
135- onClick = { onFabClick(false ) },
136- modifier = fabModifier,
137- shape = fabShape,
138- backgroundColor = fabClosedBackgroundColor,
139- contentColor = fabClosedContentColor,
140- elevation = fabElevation,
141- content = fabClosedContent,
142- )
152+ }
153+ }
154+
155+ when (state) {
156+ SpeedDialState .Expanded -> FloatingActionButton (
157+ onClick = { onFabClick(true ) },
158+ shape = fabShape,
159+ backgroundColor = fabOpenedBackgroundColor,
160+ contentColor = fabOpenedContentColor,
161+ elevation = fabElevation,
162+ content = {
163+ Box (
164+ modifier = Modifier
165+ .rotate(- fabAnimationRotateAngle)
166+ .rotate(rotation),
167+ propagateMinConstraints = true ,
168+ ) {
169+ fabOpenedContent()
170+ }
171+ },
172+ )
173+ SpeedDialState .Collapsed -> FloatingActionButton (
174+ onClick = { onFabClick(false ) },
175+ shape = fabShape,
176+ backgroundColor = fabClosedBackgroundColor,
177+ contentColor = fabClosedContentColor,
178+ elevation = fabElevation,
179+ content = {
180+ Box (
181+ modifier = Modifier .rotate(rotation),
182+ propagateMinConstraints = true ,
183+ ) {
184+ fabClosedContent()
185+ }
186+ },
187+ )
188+ }
143189 }
144190 }
145191}
146192
193+ @ExperimentalMaterialApi
147194@ExperimentalAnimationApi
148195@Preview
149196@Composable
@@ -156,6 +203,7 @@ fun PreviewSpeedDialCollapsed() {
156203 }
157204}
158205
206+ @ExperimentalMaterialApi
159207@ExperimentalAnimationApi
160208@Preview
161209@Composable
@@ -177,6 +225,7 @@ fun PreviewSpeedDialExpandedWithActions() {
177225 SpeedDial (
178226 state = SpeedDialState .Expanded ,
179227 onFabClick = {},
228+ labelContent = { Text (" Close" ) },
180229 ) {
181230 item {
182231 FabWithLabel (
@@ -196,3 +245,6 @@ fun PreviewSpeedDialExpandedWithActions() {
196245 }
197246 }
198247}
248+
249+ val SpeedDialFabSize = 56 .dp
250+ val SpeedDialMiniFabSize = 40 .dp
0 commit comments