Skip to content

Commit 66df1ab

Browse files
committed
Introduce StreamButton and StreamIconButton
1 parent 2e3e3ff commit 66df1ab

File tree

7 files changed

+547
-4
lines changed

7 files changed

+547
-4
lines changed

stream-chat-android-compose/api/stream-chat-android-compose.api

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,24 @@ public final class io/getstream/chat/android/compose/ui/components/avatar/UserAv
15411541
public static final fun UserAvatarRow-DG5NWxM (Ljava/util/List;Landroidx/compose/ui/Modifier;IFILandroidx/compose/ui/graphics/Shape;Landroidx/compose/ui/text/TextStyle;Ljava/lang/String;JLkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;II)V
15421542
}
15431543

1544+
public final class io/getstream/chat/android/compose/ui/components/button/ComposableSingletons$StreamButtonKt {
1545+
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/components/button/ComposableSingletons$StreamButtonKt;
1546+
public static field lambda-1 Lkotlin/jvm/functions/Function2;
1547+
public fun <init> ()V
1548+
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
1549+
}
1550+
1551+
public final class io/getstream/chat/android/compose/ui/components/button/ComposableSingletons$StreamIconButtonKt {
1552+
public static final field INSTANCE Lio/getstream/chat/android/compose/ui/components/button/ComposableSingletons$StreamIconButtonKt;
1553+
public static field lambda-1 Lkotlin/jvm/functions/Function2;
1554+
public static field lambda-2 Lkotlin/jvm/functions/Function2;
1555+
public static field lambda-3 Lkotlin/jvm/functions/Function2;
1556+
public fun <init> ()V
1557+
public final fun getLambda-1$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
1558+
public final fun getLambda-2$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
1559+
public final fun getLambda-3$stream_chat_android_compose_release ()Lkotlin/jvm/functions/Function2;
1560+
}
1561+
15441562
public final class io/getstream/chat/android/compose/ui/components/channels/ChannelMembersKt {
15451563
public static final fun ChannelMembers (Ljava/util/List;Landroidx/compose/ui/Modifier;Lio/getstream/chat/android/models/User;Landroidx/compose/runtime/Composer;II)V
15461564
}
@@ -3697,8 +3715,8 @@ public final class io/getstream/chat/android/compose/ui/theme/ReactionOptionsThe
36973715
public final class io/getstream/chat/android/compose/ui/theme/StreamColors {
36983716
public static final field $stable I
36993717
public static final field Companion Lio/getstream/chat/android/compose/ui/theme/StreamColors$Companion;
3700-
public synthetic fun <init> (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIILkotlin/jvm/internal/DefaultConstructorMarker;)V
3701-
public synthetic fun <init> (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
3718+
public synthetic fun <init> (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIILkotlin/jvm/internal/DefaultConstructorMarker;)V
3719+
public synthetic fun <init> (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJLkotlin/jvm/internal/DefaultConstructorMarker;)V
37023720
public final fun component1-0d7_KjU ()J
37033721
public final fun component10-0d7_KjU ()J
37043722
public final fun component11-0d7_KjU ()J
@@ -3728,18 +3746,63 @@ public final class io/getstream/chat/android/compose/ui/theme/StreamColors {
37283746
public final fun component33-0d7_KjU ()J
37293747
public final fun component34-0d7_KjU ()J
37303748
public final fun component35-0d7_KjU ()J
3749+
public final fun component36-0d7_KjU ()J
3750+
public final fun component37-0d7_KjU ()J
3751+
public final fun component38-0d7_KjU ()J
3752+
public final fun component39-0d7_KjU ()J
37313753
public final fun component4-0d7_KjU ()J
3754+
public final fun component40-0d7_KjU ()J
3755+
public final fun component41-0d7_KjU ()J
3756+
public final fun component42-0d7_KjU ()J
3757+
public final fun component43-0d7_KjU ()J
3758+
public final fun component44-0d7_KjU ()J
3759+
public final fun component45-0d7_KjU ()J
3760+
public final fun component46-0d7_KjU ()J
3761+
public final fun component47-0d7_KjU ()J
3762+
public final fun component48-0d7_KjU ()J
3763+
public final fun component49-0d7_KjU ()J
37323764
public final fun component5-0d7_KjU ()J
3765+
public final fun component50-0d7_KjU ()J
3766+
public final fun component51-0d7_KjU ()J
3767+
public final fun component52-0d7_KjU ()J
3768+
public final fun component53-0d7_KjU ()J
3769+
public final fun component54-0d7_KjU ()J
3770+
public final fun component55-0d7_KjU ()J
3771+
public final fun component56-0d7_KjU ()J
3772+
public final fun component57-0d7_KjU ()J
3773+
public final fun component58-0d7_KjU ()J
3774+
public final fun component59-0d7_KjU ()J
37333775
public final fun component6-0d7_KjU ()J
37343776
public final fun component7-0d7_KjU ()J
37353777
public final fun component8-0d7_KjU ()J
37363778
public final fun component9-0d7_KjU ()J
3737-
public final fun copy-IWRRXjM (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ)Lio/getstream/chat/android/compose/ui/theme/StreamColors;
3738-
public static synthetic fun copy-IWRRXjM$default (Lio/getstream/chat/android/compose/ui/theme/StreamColors;JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/StreamColors;
3779+
public final fun copy-IKK4sMI (JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ)Lio/getstream/chat/android/compose/ui/theme/StreamColors;
3780+
public static synthetic fun copy-IKK4sMI$default (Lio/getstream/chat/android/compose/ui/theme/StreamColors;JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJIILjava/lang/Object;)Lio/getstream/chat/android/compose/ui/theme/StreamColors;
37393781
public fun equals (Ljava/lang/Object;)Z
3782+
public final fun getAccentError-0d7_KjU ()J
3783+
public final fun getAccentPrimary-0d7_KjU ()J
37403784
public final fun getAppBackground-0d7_KjU ()J
37413785
public final fun getBarsBackground-0d7_KjU ()J
3786+
public final fun getBorderCorePrimary-0d7_KjU ()J
3787+
public final fun getBorderCoreSurfaceSubtle-0d7_KjU ()J
37423788
public final fun getBorders-0d7_KjU ()J
3789+
public final fun getButtonStyleGhostBg-0d7_KjU ()J
3790+
public final fun getButtonStyleGhostBorder-0d7_KjU ()J
3791+
public final fun getButtonStyleGhostTextPrimary-0d7_KjU ()J
3792+
public final fun getButtonStyleGhostTextSecondary-0d7_KjU ()J
3793+
public final fun getButtonStyleOutlineBg-0d7_KjU ()J
3794+
public final fun getButtonStyleOutlineBorder-0d7_KjU ()J
3795+
public final fun getButtonStyleOutlineText-0d7_KjU ()J
3796+
public final fun getButtonTypeDestructiveBg-0d7_KjU ()J
3797+
public final fun getButtonTypeDestructiveBorder-0d7_KjU ()J
3798+
public final fun getButtonTypeDestructiveText-0d7_KjU ()J
3799+
public final fun getButtonTypeDestructiveTextInverse-0d7_KjU ()J
3800+
public final fun getButtonTypePrimaryBg-0d7_KjU ()J
3801+
public final fun getButtonTypePrimaryBgDisabled-0d7_KjU ()J
3802+
public final fun getButtonTypePrimaryBorder-0d7_KjU ()J
3803+
public final fun getButtonTypePrimaryText-0d7_KjU ()J
3804+
public final fun getButtonTypePrimaryTextDisabled-0d7_KjU ()J
3805+
public final fun getButtonTypeSecondaryTextDisabled-0d7_KjU ()J
37433806
public final fun getDeletedMessagesBackground-0d7_KjU ()J
37443807
public final fun getDisabled-0d7_KjU ()J
37453808
public final fun getErrorAccent-0d7_KjU ()J
@@ -3765,9 +3828,12 @@ public final class io/getstream/chat/android/compose/ui/theme/StreamColors {
37653828
public final fun getPrimaryAccent-0d7_KjU ()J
37663829
public final fun getShowMoreCountText-0d7_KjU ()J
37673830
public final fun getShowMoreOverlay-0d7_KjU ()J
3831+
public final fun getStateBgDisabled-0d7_KjU ()J
3832+
public final fun getStateTextDisabled-0d7_KjU ()J
37683833
public final fun getTextHighEmphasis-0d7_KjU ()J
37693834
public final fun getTextHighEmphasisInverse-0d7_KjU ()J
37703835
public final fun getTextLowEmphasis-0d7_KjU ()J
3836+
public final fun getTextPrimary-0d7_KjU ()J
37713837
public final fun getThreadSeparatorGradientEnd-0d7_KjU ()J
37723838
public final fun getThreadSeparatorGradientStart-0d7_KjU ()J
37733839
public final fun getVideoBackgroundMediaGalleryPicker-0d7_KjU ()J
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright (c) 2014-2026 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.chat.android.compose.ui.components.button
18+
19+
import androidx.compose.foundation.interaction.MutableInteractionSource
20+
import androidx.compose.foundation.layout.Arrangement
21+
import androidx.compose.foundation.layout.Column
22+
import androidx.compose.foundation.layout.Row
23+
import androidx.compose.foundation.layout.RowScope
24+
import androidx.compose.foundation.layout.defaultMinSize
25+
import androidx.compose.foundation.layout.padding
26+
import androidx.compose.foundation.shape.RoundedCornerShape
27+
import androidx.compose.material3.Surface
28+
import androidx.compose.material3.Text
29+
import androidx.compose.runtime.Composable
30+
import androidx.compose.runtime.remember
31+
import androidx.compose.ui.Alignment
32+
import androidx.compose.ui.Modifier
33+
import androidx.compose.ui.semantics.Role
34+
import androidx.compose.ui.semantics.role
35+
import androidx.compose.ui.semantics.semantics
36+
import androidx.compose.ui.tooling.preview.Preview
37+
import androidx.compose.ui.unit.dp
38+
import io.getstream.chat.android.compose.ui.theme.ChatTheme
39+
import io.getstream.chat.android.compose.ui.theme.StreamSpacings
40+
41+
@Composable
42+
internal fun StreamButton(
43+
onClick: () -> Unit,
44+
modifier: Modifier = Modifier,
45+
enabled: Boolean = true,
46+
style: StreamButtonStyle = StreamButtonStyleDefaults.primarySolid,
47+
size: StreamButtonSize = StreamButtonSize.Medium,
48+
content: @Composable RowScope.() -> Unit,
49+
) {
50+
Surface(
51+
onClick = onClick,
52+
modifier = modifier.semantics { role = Role.Button },
53+
enabled = enabled,
54+
shape = RoundedCornerShape(percent = 50),
55+
color = style.containerColor(enabled),
56+
contentColor = style.contentColor(enabled),
57+
border = style.border(enabled),
58+
interactionSource = remember(::MutableInteractionSource),
59+
) {
60+
Row(
61+
Modifier
62+
.defaultMinSize(minHeight = size.minimumSize)
63+
.padding(horizontal = StreamSpacings.sm, vertical = StreamSpacings.xs),
64+
horizontalArrangement = Arrangement.Center,
65+
verticalAlignment = Alignment.CenterVertically,
66+
content = content,
67+
)
68+
}
69+
}
70+
71+
@Preview(showBackground = true)
72+
@Composable
73+
private fun StreamButtonPreview() {
74+
ChatTheme {
75+
val styles = listOf(
76+
StreamButtonStyleDefaults.primarySolid to "Primary Solid",
77+
StreamButtonStyleDefaults.primaryGhost to "Primary Ghost",
78+
StreamButtonStyleDefaults.secondaryOutline to "Secondary Outline",
79+
StreamButtonStyleDefaults.secondaryGhost to "Secondary Ghost",
80+
StreamButtonStyleDefaults.destructiveSolid to "Destructive Solid",
81+
StreamButtonStyleDefaults.destructiveGhost to "Destructive Ghost",
82+
)
83+
84+
Column(
85+
modifier = Modifier.padding(StreamSpacings.md),
86+
verticalArrangement = Arrangement.spacedBy(StreamSpacings.xs),
87+
) {
88+
styles.forEach { (style, name) ->
89+
Row(horizontalArrangement = Arrangement.spacedBy(StreamSpacings.md)) {
90+
StreamButton(
91+
onClick = {},
92+
style = style,
93+
modifier = Modifier.defaultMinSize(150.dp),
94+
) {
95+
Text(name)
96+
}
97+
StreamButton(
98+
onClick = {},
99+
style = style,
100+
enabled = false,
101+
modifier = Modifier.defaultMinSize(150.dp),
102+
) {
103+
Text(name)
104+
}
105+
}
106+
}
107+
}
108+
}
109+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2014-2026 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.chat.android.compose.ui.components.button
18+
19+
import androidx.compose.ui.unit.Dp
20+
import androidx.compose.ui.unit.dp
21+
22+
internal enum class StreamButtonSize(val minimumSize: Dp) {
23+
Small(32.dp), Medium(40.dp), Large(48.dp)
24+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright (c) 2014-2026 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.chat.android.compose.ui.components.button
18+
19+
import androidx.compose.foundation.BorderStroke
20+
import androidx.compose.runtime.Composable
21+
import androidx.compose.runtime.Stable
22+
import androidx.compose.ui.graphics.Color
23+
import androidx.compose.ui.unit.dp
24+
import io.getstream.chat.android.compose.ui.theme.ChatTheme
25+
26+
internal data class StreamButtonStyle(
27+
val containerColor: Color,
28+
val contentColor: Color,
29+
val border: BorderStroke?,
30+
val disabledContainerColor: Color,
31+
val disabledContentColor: Color,
32+
val disabledBorder: BorderStroke?,
33+
)
34+
35+
@Stable
36+
internal fun StreamButtonStyle.contentColor(enabled: Boolean) =
37+
if (enabled) contentColor else disabledContentColor
38+
39+
@Stable
40+
internal fun StreamButtonStyle.containerColor(enabled: Boolean) =
41+
if (enabled) containerColor else disabledContainerColor
42+
43+
@Stable
44+
internal fun StreamButtonStyle.border(enabled: Boolean) =
45+
if (enabled) border else disabledBorder
46+
47+
internal object StreamButtonStyleDefaults {
48+
val primarySolid: StreamButtonStyle
49+
@Composable
50+
get() {
51+
val colors = ChatTheme.colors
52+
return StreamButtonStyle(
53+
containerColor = colors.buttonTypePrimaryBg,
54+
contentColor = colors.buttonTypePrimaryText,
55+
border = BorderStroke(1.dp, colors.buttonTypePrimaryBorder),
56+
disabledContainerColor = colors.buttonTypePrimaryBgDisabled,
57+
disabledContentColor = colors.buttonTypePrimaryTextDisabled,
58+
disabledBorder = null,
59+
)
60+
}
61+
val primaryGhost: StreamButtonStyle
62+
@Composable
63+
get() {
64+
val colors = ChatTheme.colors
65+
return StreamButtonStyle(
66+
containerColor = colors.buttonStyleGhostBg,
67+
contentColor = colors.buttonStyleGhostTextPrimary,
68+
border = BorderStroke(1.dp, colors.buttonStyleGhostBorder),
69+
disabledContainerColor = colors.buttonStyleGhostBg,
70+
disabledContentColor = colors.stateTextDisabled,
71+
disabledBorder = BorderStroke(1.dp, colors.buttonStyleGhostBorder),
72+
)
73+
}
74+
val secondaryOutline: StreamButtonStyle
75+
@Composable
76+
get() {
77+
val colors = ChatTheme.colors
78+
return StreamButtonStyle(
79+
containerColor = colors.buttonStyleOutlineBg,
80+
contentColor = colors.buttonStyleOutlineText,
81+
border = BorderStroke(1.dp, colors.buttonStyleOutlineBorder),
82+
disabledContainerColor = colors.buttonStyleOutlineBg,
83+
disabledContentColor = colors.stateTextDisabled,
84+
disabledBorder = BorderStroke(1.dp, colors.buttonStyleOutlineBorder),
85+
)
86+
}
87+
val secondaryGhost: StreamButtonStyle
88+
@Composable
89+
get() {
90+
val colors = ChatTheme.colors
91+
return StreamButtonStyle(
92+
containerColor = colors.buttonStyleGhostBg,
93+
contentColor = colors.buttonStyleGhostTextSecondary,
94+
border = BorderStroke(1.dp, colors.buttonStyleGhostBorder),
95+
disabledContainerColor = colors.buttonStyleGhostBg,
96+
disabledContentColor = colors.buttonTypeSecondaryTextDisabled,
97+
disabledBorder = BorderStroke(1.dp, colors.buttonStyleGhostBorder),
98+
)
99+
}
100+
101+
val destructiveSolid: StreamButtonStyle
102+
@Composable
103+
get() {
104+
val colors = ChatTheme.colors
105+
return StreamButtonStyle(
106+
containerColor = colors.buttonTypeDestructiveBg,
107+
contentColor = colors.buttonTypeDestructiveText,
108+
border = BorderStroke(1.dp, colors.buttonTypeDestructiveBorder),
109+
disabledContainerColor = colors.stateBgDisabled,
110+
disabledContentColor = colors.stateTextDisabled,
111+
disabledBorder = null,
112+
)
113+
}
114+
115+
val destructiveGhost: StreamButtonStyle
116+
@Composable
117+
get() {
118+
val colors = ChatTheme.colors
119+
return StreamButtonStyle(
120+
containerColor = colors.buttonStyleGhostBg,
121+
contentColor = colors.buttonTypeDestructiveTextInverse,
122+
border = BorderStroke(1.dp, colors.buttonStyleGhostBorder),
123+
disabledContainerColor = colors.buttonStyleGhostBg,
124+
disabledContentColor = colors.stateTextDisabled,
125+
disabledBorder = BorderStroke(1.dp, colors.buttonStyleGhostBorder),
126+
)
127+
}
128+
}

0 commit comments

Comments
 (0)