@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.Box
99import androidx.compose.foundation.layout.Column
1010import androidx.compose.foundation.layout.PaddingValues
1111import androidx.compose.foundation.layout.Row
12+ import androidx.compose.foundation.layout.fillMaxSize
1213import androidx.compose.foundation.layout.fillMaxWidth
1314import androidx.compose.foundation.layout.padding
1415import androidx.compose.foundation.layout.requiredHeight
@@ -24,6 +25,7 @@ import androidx.compose.material3.Text
2425import androidx.compose.runtime.Composable
2526import androidx.compose.ui.Alignment
2627import androidx.compose.ui.Modifier
28+ import androidx.compose.ui.draw.clip
2729import androidx.compose.ui.graphics.Color
2830import androidx.compose.ui.graphics.ColorFilter
2931import androidx.compose.ui.graphics.graphicsLayer
@@ -33,11 +35,16 @@ import androidx.compose.ui.text.style.TextOverflow
3335import androidx.compose.ui.tooling.preview.Preview
3436import androidx.compose.ui.unit.Dp
3537import androidx.compose.ui.unit.dp
38+ import dev.chrisbanes.haze.HazeState
39+ import dev.chrisbanes.haze.HazeStyle
40+ import dev.chrisbanes.haze.HazeTint
41+ import dev.chrisbanes.haze.hazeEffect
42+ import dev.chrisbanes.haze.hazeSource
43+ import dev.chrisbanes.haze.rememberHazeState
3644import to.bitkit.R
3745import to.bitkit.ui.shared.modifiers.alphaFeedback
3846import to.bitkit.ui.shared.modifiers.clickableAlpha
3947import to.bitkit.ui.shared.modifiers.rememberDebouncedClick
40- import to.bitkit.ui.shared.util.glassBlur
4148import to.bitkit.ui.shared.util.primaryButtonStyle
4249import to.bitkit.ui.theme.AppButtonDefaults
4350import to.bitkit.ui.theme.AppThemeSurface
@@ -76,12 +83,6 @@ enum class ButtonSize {
7683 Small -> 8 .dp
7784 Large -> 6 .dp
7885 }
79- val secondaryBlurRadius: Dp
80- get() = when (this ) {
81- Small -> 5 .dp
82- Large -> 8 .dp
83- }
84-
8586 fun secondaryBorder (enabled : Boolean ): BorderStroke = when (this ) {
8687 Large -> BorderStroke (2 .dp, if (enabled) Colors .Gray4 else Color .Transparent )
8788 Small -> BorderStroke (1 .dp, if (enabled) Colors .White16 else Color .Transparent )
@@ -170,53 +171,75 @@ fun SecondaryButton(
170171 size : ButtonSize = ButtonSize .Large ,
171172 enabled : Boolean = true,
172173 fullWidth : Boolean = true,
174+ hazeState : HazeState ? = null,
173175) {
174176 val contentPadding = PaddingValues (horizontal = size.secondaryHorizontalPadding.takeIf { text != null } ? : 0 .dp)
175177 val border = size.secondaryBorder(enabled)
176178 val contentColor = when (size) {
177179 ButtonSize .Large -> Colors .White80
178180 ButtonSize .Small -> Colors .White64
179181 }
180- OutlinedButton (
181- onClick = rememberDebouncedClick(onClick = onClick),
182- enabled = enabled && ! isLoading,
183- colors = AppButtonDefaults .secondaryColors.copy(contentColor = contentColor),
184- contentPadding = contentPadding,
185- border = border,
182+ // hazeEffect must be on a Box wrapper (not OutlinedButton — Material's Surface draws over it)
183+ // and AFTER size modifiers (Haze needs to know dimensions)
184+ val buttonShape = MaterialTheme .shapes.extraLarge
185+ Box (
186186 modifier = modifier
187187 .then(if (fullWidth) Modifier .fillMaxWidth() else Modifier )
188188 .requiredHeight(size.height)
189- .glassBlur(blurRadius = size.secondaryBlurRadius)
190- ) {
191- if (isLoading) {
192- GradientCircularProgressIndicator (
193- strokeWidth = 2 .dp,
194- modifier = Modifier .size(size.height / 2 )
189+ .clip(buttonShape)
190+ .then(
191+ if (hazeState != null ) {
192+ Modifier .hazeEffect(
193+ state = hazeState,
194+ style = HazeStyle (
195+ blurRadius = 12 .dp,
196+ backgroundColor = Color .Black ,
197+ tint = HazeTint (Color .Black .copy(alpha = 0.2f )),
198+ ),
199+ )
200+ } else {
201+ Modifier
202+ }
195203 )
196- } else {
197- Row (
198- verticalAlignment = Alignment .CenterVertically ,
199- horizontalArrangement = Arrangement .spacedBy(size.secondaryGap),
200- ) {
201- if (icon != null ) {
202- Box (
203- modifier = if (enabled) {
204- Modifier
205- } else {
206- Modifier .graphicsLayer {
207- colorFilter = ColorFilter .tint(Colors .White32 )
204+ ) {
205+ OutlinedButton (
206+ onClick = rememberDebouncedClick(onClick = onClick),
207+ enabled = enabled && ! isLoading,
208+ colors = AppButtonDefaults .secondaryColors.copy(contentColor = contentColor),
209+ contentPadding = contentPadding,
210+ border = border,
211+ modifier = if (fullWidth) Modifier .fillMaxSize() else Modifier ,
212+ ) {
213+ if (isLoading) {
214+ GradientCircularProgressIndicator (
215+ strokeWidth = 2 .dp,
216+ modifier = Modifier .size(size.height / 2 )
217+ )
218+ } else {
219+ Row (
220+ verticalAlignment = Alignment .CenterVertically ,
221+ horizontalArrangement = Arrangement .spacedBy(size.secondaryGap),
222+ ) {
223+ if (icon != null ) {
224+ Box (
225+ modifier = if (enabled) {
226+ Modifier
227+ } else {
228+ Modifier .graphicsLayer {
229+ colorFilter = ColorFilter .tint(Colors .White32 )
230+ }
208231 }
232+ ) {
233+ icon()
209234 }
210- ) {
211- icon()
212235 }
213- }
214- text?. let {
215- Text (
216- text = text ,
217- maxLines = 1 ,
218- overflow = TextOverflow . Ellipsis ,
219- )
236+ text?. let {
237+ Text (
238+ text = text,
239+ maxLines = 1 ,
240+ overflow = TextOverflow . Ellipsis ,
241+ )
242+ }
220243 }
221244 }
222245 }
@@ -278,7 +301,7 @@ fun TertiaryButton(
278301 }
279302}
280303
281- @Preview(showBackground = true )
304+ @Preview
282305@Composable
283306private fun PrimaryButtonPreview () {
284307 AppThemeSurface {
@@ -405,33 +428,39 @@ private fun PrimaryButtonPreview() {
405428 }
406429}
407430
408- @Preview(showBackground = true )
431+ @Preview
409432@Composable
410433private fun SecondaryButtonPreview () {
434+ val hazeState = rememberHazeState()
411435 AppThemeSurface {
412436 Box {
413- Image (
414- painter = painterResource(R .drawable.lightning),
415- contentDescription = null ,
416- contentScale = ContentScale .Crop ,
417- modifier = Modifier .matchParentSize()
418- )
437+ Box (
438+ modifier = Modifier
439+ .matchParentSize()
440+ .hazeSource(hazeState)
441+ ) {
442+ Image (
443+ painter = painterResource(R .drawable.lightning),
444+ contentDescription = null ,
445+ contentScale = ContentScale .Crop ,
446+ modifier = Modifier .matchParentSize()
447+ )
448+ }
419449 Column (
420450 verticalArrangement = Arrangement .spacedBy(8 .dp),
421451 modifier = Modifier .padding(16 .dp)
422452 ) {
423- SecondaryButton (
424- text = " Secondary" ,
425- onClick = {},
426- )
453+ SecondaryButton (text = " Secondary" , hazeState = hazeState, onClick = {})
427454 SecondaryButton (
428455 text = " Secondary With padding" ,
429- modifier = Modifier .padding(horizontal = 32 .dp) ,
456+ hazeState = hazeState ,
430457 onClick = {},
458+ modifier = Modifier .padding(horizontal = 32 .dp)
431459 )
432460 SecondaryButton (
433461 text = " Secondary With Icon" ,
434462 onClick = {},
463+ hazeState = hazeState,
435464 icon = {
436465 Icon (
437466 imageVector = Icons .Filled .Favorite ,
@@ -443,12 +472,14 @@ private fun SecondaryButtonPreview() {
443472 SecondaryButton (
444473 text = " Secondary Loading" ,
445474 isLoading = true ,
475+ hazeState = hazeState,
446476 onClick = {},
447477 )
448478 SecondaryButton (
449479 text = " Secondary Disabled" ,
450480 onClick = {},
451481 enabled = false ,
482+ hazeState = hazeState,
452483 icon = {
453484 Icon (
454485 imageVector = Icons .Filled .Favorite ,
@@ -461,12 +492,14 @@ private fun SecondaryButtonPreview() {
461492 text = " Secondary Small" ,
462493 size = ButtonSize .Small ,
463494 fullWidth = false ,
495+ hazeState = hazeState,
464496 onClick = {},
465497 )
466498 SecondaryButton (
467499 text = " Secondary Small Loading" ,
468500 size = ButtonSize .Small ,
469501 isLoading = true ,
502+ hazeState = hazeState,
470503 onClick = {},
471504 )
472505 SecondaryButton (
@@ -485,6 +518,7 @@ private fun SecondaryButtonPreview() {
485518 onClick = {},
486519 fullWidth = false ,
487520 size = ButtonSize .Large ,
521+ hazeState = hazeState,
488522 icon = {
489523 Icon (
490524 imageVector = Icons .Filled .Favorite ,
@@ -513,7 +547,7 @@ private fun SecondaryButtonPreview() {
513547 }
514548}
515549
516- @Preview(showBackground = true )
550+ @Preview
517551@Composable
518552private fun TertiaryButtonPreview () {
519553 AppThemeSurface {
0 commit comments