11package dev.paulee.ui.components
22
3- import androidx.compose.foundation.background
3+ import androidx.compose.animation.animateColorAsState
4+ import androidx.compose.animation.core.tween
5+ import androidx.compose.foundation.BorderStroke
46import androidx.compose.foundation.clickable
5- import androidx.compose.foundation.layout.Box
6- import androidx.compose.foundation.layout.Row
7- import androidx.compose.foundation.layout.padding
8- import androidx.compose.foundation.layout.width
7+ import androidx.compose.foundation.layout.*
98import androidx.compose.foundation.shape.RoundedCornerShape
109import androidx.compose.material.LocalTextStyle
10+ import androidx.compose.material.MaterialTheme
11+ import androidx.compose.material.Surface
1112import androidx.compose.material.Text
1213import androidx.compose.runtime.Composable
14+ import androidx.compose.runtime.getValue
15+ import androidx.compose.runtime.remember
1316import androidx.compose.ui.Alignment
1417import androidx.compose.ui.Modifier
15- import androidx.compose.ui.graphics.Color
18+ import androidx.compose.ui.platform.LocalDensity
1619import androidx.compose.ui.text.AnnotatedString
20+ import androidx.compose.ui.text.font.FontWeight
1721import androidx.compose.ui.text.rememberTextMeasurer
22+ import androidx.compose.ui.unit.Dp
1823import androidx.compose.ui.unit.dp
24+ import androidx.compose.ui.unit.sp
1925
2026@Composable
2127fun TwoSegmentButton (
@@ -26,46 +32,67 @@ fun TwoSegmentButton(
2632 modifier : Modifier = Modifier ,
2733) {
2834 val textMeasurer = rememberTextMeasurer()
35+ val density = LocalDensity .current
2936
30- val leftWidth = textMeasurer.measure(
31- text = AnnotatedString (left),
32- style = LocalTextStyle .current
33- ).size.width
37+ val style = LocalTextStyle .current.copy(fontSize = 13 .sp, fontWeight = FontWeight .Medium )
3438
35- val rightWidth = textMeasurer.measure(
36- text = AnnotatedString (right),
37- style = LocalTextStyle .current
38- ).size.width
39+ val maxSegmentWidth = remember(left, right, style) {
40+ val leftWidth = textMeasurer.measure(text = AnnotatedString (left), style = style).size.width
41+ val rightWidth = textMeasurer.measure(text = AnnotatedString (right), style = style).size.width
3942
40- val maxSegmentWidth = (maxOf(leftWidth, rightWidth) + 32 ).dp
43+ with (density) { maxOf(leftWidth, rightWidth).toDp() + 30 .dp }
44+ }
4145
42- Row (modifier = modifier) {
43- Box (
44- modifier = Modifier
45- .width(maxSegmentWidth)
46- .clickable { onClick( false ) }
47- .background(
48- if ( ! selected) Color . Gray else Color . LightGray ,
49- shape = RoundedCornerShape (topStart = 8 .dp, bottomStart = 8 .dp)
50- )
51- .padding(horizontal = 16 .dp, vertical = 8 .dp) ,
52- contentAlignment = Alignment . Center
46+ Surface (
47+ modifier = modifier,
48+ shape = RoundedCornerShape ( 50 .dp),
49+ color = MaterialTheme .colors.onSurface.copy(alpha = 0.06f ),
50+ border = BorderStroke ( 1 .dp, MaterialTheme .colors.onSurface.copy(alpha = 0.12f )),
51+ elevation = 0 .dp
52+ ) {
53+ Row (
54+ modifier = Modifier .padding( 3 .dp),
55+ verticalAlignment = Alignment . CenterVertically ,
56+ horizontalArrangement = Arrangement .spacedBy( 3 .dp)
5357 ) {
54- Text (text = left)
58+ SegmentToggleItem (
59+ text = left, width = maxSegmentWidth, selected = ! selected, onClick = { onClick(false ) })
60+
61+ SegmentToggleItem (
62+ text = right, width = maxSegmentWidth, selected = selected, onClick = { onClick(true ) })
5563 }
64+ }
65+ }
66+
67+ @Composable
68+ private fun SegmentToggleItem (
69+ text : String ,
70+ width : Dp ,
71+ selected : Boolean ,
72+ onClick : () -> Unit ,
73+ ) {
74+ val bg by animateColorAsState(
75+ targetValue = if (selected) MaterialTheme .colors.primary.copy(alpha = 0.16f )
76+ else MaterialTheme .colors.surface, animationSpec = tween(180 )
77+ )
78+
79+ val textColor by animateColorAsState(
80+ targetValue = if (selected) MaterialTheme .colors.primary else MaterialTheme .colors.onSurface.copy(alpha = 0.8f ),
81+ animationSpec = tween(180 )
82+ )
5683
84+ Surface (
85+ color = bg,
86+ shape = RoundedCornerShape (50 .dp),
87+ border = BorderStroke (1 .dp, MaterialTheme .colors.onSurface.copy(alpha = if (selected) 0.12f else 0.04f ))
88+ ) {
5789 Box (
58- modifier = Modifier
59- .width(maxSegmentWidth)
60- .clickable { onClick(true ) }
61- .background(
62- if (selected) Color .Gray else Color .LightGray ,
63- shape = RoundedCornerShape (topEnd = 8 .dp, bottomEnd = 8 .dp)
64- )
65- .padding(horizontal = 16 .dp, vertical = 8 .dp),
90+ modifier = Modifier .width(width).clickable(onClick = onClick).padding(horizontal = 14 .dp, vertical = 6 .dp),
6691 contentAlignment = Alignment .Center
6792 ) {
68- Text (text = right)
93+ Text (
94+ text = text, color = textColor, fontSize = 13 .sp, fontWeight = FontWeight .Medium
95+ )
6996 }
7097 }
7198}
0 commit comments