Skip to content

Commit ce263bd

Browse files
authored
Merge pull request #516 from synonymdev/fix/primary-bt-width
fix: Primary Button width
2 parents 07bf511 + a32f403 commit ce263bd

File tree

2 files changed

+102
-47
lines changed

2 files changed

+102
-47
lines changed

app/src/main/java/to/bitkit/ui/components/Button.kt

Lines changed: 67 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import androidx.compose.ui.text.style.TextOverflow
3030
import androidx.compose.ui.tooling.preview.Preview
3131
import androidx.compose.ui.unit.Dp
3232
import androidx.compose.ui.unit.dp
33+
import to.bitkit.ui.shared.modifiers.alphaFeedback
3334
import to.bitkit.ui.shared.util.primaryButtonStyle
3435
import to.bitkit.ui.theme.AppButtonDefaults
3536
import to.bitkit.ui.theme.AppThemeSurface
@@ -72,57 +73,49 @@ fun PrimaryButton(
7273
containerColor = Color.Transparent,
7374
disabledContainerColor = Color.Transparent
7475
),
75-
contentPadding = PaddingValues(0.dp),
76+
contentPadding = contentPadding,
7677
shape = buttonShape,
77-
modifier = Modifier
78+
modifier = modifier
7879
.then(if (fullWidth) Modifier.fillMaxWidth() else Modifier)
7980
.requiredHeight(size.height)
80-
.then(modifier)
81+
.primaryButtonStyle(
82+
isEnabled = enabled && !isLoading,
83+
shape = buttonShape,
84+
primaryColor = color
85+
)
86+
.alphaFeedback(enabled = enabled && !isLoading)
8187
) {
82-
Box(
83-
contentAlignment = Alignment.Center,
84-
modifier = Modifier
85-
.then(if (fullWidth) Modifier.fillMaxWidth() else Modifier)
86-
.requiredHeight(size.height)
87-
.primaryButtonStyle(
88-
isEnabled = enabled && !isLoading,
89-
shape = buttonShape,
90-
primaryColor = color
91-
)
92-
.padding(contentPadding)
93-
) {
94-
if (isLoading) {
95-
CircularProgressIndicator(
96-
color = Colors.White32,
97-
strokeWidth = 2.dp,
98-
modifier = Modifier.size(size.height / 2)
99-
)
100-
} else {
101-
Row(
102-
verticalAlignment = Alignment.CenterVertically,
103-
horizontalArrangement = Arrangement.spacedBy(8.dp),
104-
) {
105-
if (icon != null) {
106-
Box(
107-
modifier = if (enabled) {
108-
Modifier
109-
} else {
110-
Modifier.graphicsLayer {
111-
colorFilter = ColorFilter.tint(Colors.White32)
112-
}
88+
if (isLoading) {
89+
CircularProgressIndicator(
90+
color = Colors.White32,
91+
strokeWidth = 2.dp,
92+
modifier = Modifier.size(size.height / 2)
93+
)
94+
} else {
95+
Row(
96+
verticalAlignment = Alignment.CenterVertically,
97+
horizontalArrangement = Arrangement.spacedBy(8.dp),
98+
) {
99+
if (icon != null) {
100+
Box(
101+
modifier = if (enabled) {
102+
Modifier
103+
} else {
104+
Modifier.graphicsLayer {
105+
colorFilter = ColorFilter.tint(Colors.White32)
113106
}
114-
) {
115-
icon()
116107
}
117-
}
118-
text?.let {
119-
Text(
120-
text = text,
121-
maxLines = 1,
122-
overflow = TextOverflow.Ellipsis,
123-
)
108+
) {
109+
icon()
124110
}
125111
}
112+
text?.let {
113+
Text(
114+
text = text,
115+
maxLines = 1,
116+
overflow = TextOverflow.Ellipsis,
117+
)
118+
}
126119
}
127120
}
128121
}
@@ -147,10 +140,9 @@ fun SecondaryButton(
147140
colors = AppButtonDefaults.secondaryColors,
148141
contentPadding = contentPadding,
149142
border = border,
150-
modifier = Modifier
143+
modifier = modifier
151144
.then(if (fullWidth) Modifier.fillMaxWidth() else Modifier)
152145
.requiredHeight(size.height)
153-
.then(modifier)
154146
) {
155147
if (isLoading) {
156148
CircularProgressIndicator(
@@ -205,10 +197,9 @@ fun TertiaryButton(
205197
enabled = enabled && !isLoading,
206198
colors = AppButtonDefaults.tertiaryColors,
207199
contentPadding = contentPadding,
208-
modifier = Modifier
200+
modifier = modifier
209201
.then(if (fullWidth) Modifier.fillMaxWidth() else Modifier)
210202
.requiredHeight(size.height)
211-
.then(modifier)
212203
) {
213204
if (isLoading) {
214205
CircularProgressIndicator(
@@ -258,6 +249,11 @@ private fun PrimaryButtonPreview() {
258249
text = "Primary",
259250
onClick = {},
260251
)
252+
PrimaryButton(
253+
text = "Primary with padding",
254+
modifier = Modifier.padding(horizontal = 32.dp),
255+
onClick = {},
256+
)
261257
PrimaryButton(
262258
text = "Primary With Icon",
263259
onClick = {},
@@ -292,6 +288,25 @@ private fun PrimaryButtonPreview() {
292288
size = ButtonSize.Small,
293289
onClick = {},
294290
)
291+
Row(
292+
modifier = Modifier.fillMaxWidth(),
293+
horizontalArrangement = Arrangement.spacedBy(8.dp)
294+
) {
295+
PrimaryButton(
296+
text = "Primary Small",
297+
fullWidth = false,
298+
size = ButtonSize.Small,
299+
modifier = Modifier.weight(1f),
300+
onClick = {},
301+
)
302+
PrimaryButton(
303+
text = "Primary Small",
304+
fullWidth = false,
305+
size = ButtonSize.Small,
306+
modifier = Modifier.weight(1f),
307+
onClick = {},
308+
)
309+
}
295310
PrimaryButton(
296311
text = "Primary Small Color Not Full",
297312
size = ButtonSize.Small,
@@ -360,6 +375,11 @@ private fun SecondaryButtonPreview() {
360375
text = "Secondary",
361376
onClick = {},
362377
)
378+
SecondaryButton(
379+
text = "Secondary With padding",
380+
modifier = Modifier.padding(horizontal = 32.dp),
381+
onClick = {},
382+
)
363383
SecondaryButton(
364384
text = "Secondary With Icon",
365385
onClick = {},

app/src/main/java/to/bitkit/ui/shared/modifiers/ClickableAlpha.kt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ package to.bitkit.ui.shared.modifiers
22

33
import androidx.compose.animation.core.Animatable
44
import androidx.compose.foundation.gestures.detectTapGestures
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.remember
7+
import androidx.compose.runtime.rememberCoroutineScope
58
import androidx.compose.ui.Modifier
9+
import androidx.compose.ui.graphics.graphicsLayer
610
import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
11+
import androidx.compose.ui.input.pointer.pointerInput
712
import androidx.compose.ui.layout.Measurable
813
import androidx.compose.ui.layout.MeasureResult
914
import androidx.compose.ui.layout.MeasureScope
@@ -101,3 +106,33 @@ private class ClickableAlphaNode(
101106
}
102107
}
103108
}
109+
110+
/**
111+
* Applies alpha animation feedback on press without consuming click events.
112+
* This allows the Button's onClick to work while providing full-area visual feedback.
113+
*/
114+
@Composable
115+
fun Modifier.alphaFeedback(
116+
pressedAlpha: Float = 0.7f,
117+
enabled: Boolean = true,
118+
): Modifier = if (enabled) {
119+
val animatable = remember { Animatable(1f) }
120+
val scope = rememberCoroutineScope()
121+
122+
this
123+
.pointerInput(Unit) {
124+
detectTapGestures(
125+
onPress = {
126+
scope.launch { animatable.animateTo(pressedAlpha) }
127+
tryAwaitRelease()
128+
scope.launch { animatable.animateTo(1f) }
129+
},
130+
onTap = null // Don't consume tap - let Button handle it
131+
)
132+
}
133+
.graphicsLayer {
134+
alpha = animatable.value
135+
}
136+
} else {
137+
this
138+
}

0 commit comments

Comments
 (0)