1
1
package com.spendesk.grapes.compose.section
2
2
3
+ import androidx.compose.foundation.layout.Arrangement
4
+ import androidx.compose.foundation.layout.Box
3
5
import androidx.compose.foundation.layout.Column
6
+ import androidx.compose.foundation.layout.PaddingValues
7
+ import androidx.compose.foundation.layout.Row
4
8
import androidx.compose.foundation.layout.fillMaxWidth
5
9
import androidx.compose.foundation.layout.height
6
10
import androidx.compose.foundation.layout.padding
11
+ import androidx.compose.foundation.layout.widthIn
12
+ import androidx.compose.material3.ButtonColors
7
13
import androidx.compose.material3.Card
8
14
import androidx.compose.material3.CardDefaults
9
15
import androidx.compose.material3.Text
16
+ import androidx.compose.material3.TextButton
10
17
import androidx.compose.runtime.Composable
18
+ import androidx.compose.ui.Alignment
11
19
import androidx.compose.ui.Modifier
20
+ import androidx.compose.ui.text.style.TextOverflow
12
21
import androidx.compose.ui.tooling.preview.Preview
13
22
import androidx.compose.ui.unit.dp
14
23
import com.spendesk.grapes.compose.internal.Slot
@@ -22,6 +31,7 @@ import com.spendesk.grapes.compose.theme.GrapesTheme
22
31
fun GrapesSection (
23
32
title : String ,
24
33
modifier : Modifier = Modifier ,
34
+ action : @Composable (GrapesSectionActionScope .() -> Unit )? = null,
25
35
content : @Composable () -> Unit ,
26
36
) {
27
37
Card (
@@ -33,28 +43,128 @@ fun GrapesSection(
33
43
),
34
44
) {
35
45
Column (
36
- modifier = Modifier .padding(vertical = GrapesTheme .dimensions.unit8),
46
+ modifier = Modifier
47
+ .padding(vertical = GrapesTheme .dimensions.unit8)
48
+ ) {
49
+ Row (
50
+ verticalAlignment = Alignment .CenterVertically ,
51
+ horizontalArrangement = Arrangement .SpaceBetween ,
52
+ ) {
53
+ Text (
54
+ text = title,
55
+ style = GrapesTheme .typography.titleS,
56
+ color = GrapesTheme .colors.contentSecondaryBGSecondary,
57
+ maxLines = 1 ,
58
+ overflow = TextOverflow .Ellipsis ,
59
+ modifier = Modifier
60
+ .weight(1f )
61
+ .padding(
62
+ horizontal = GrapesTheme .dimensions.unit16,
63
+ vertical = GrapesTheme .dimensions.unit8,
64
+ )
65
+ )
66
+ if (action != null ) {
67
+ Box {
68
+ GrapesSectionActionScope .action()
69
+ }
70
+ }
71
+ }
72
+ content()
73
+ }
74
+ }
75
+ }
76
+
77
+ object GrapesSectionActionScope {
78
+
79
+ @Composable
80
+ fun Action (
81
+ title : String ,
82
+ modifier : Modifier = Modifier ,
83
+ enabled : Boolean = true,
84
+ onClick : () -> Unit ,
85
+ ) {
86
+ TextButton (
87
+ onClick = onClick,
88
+ contentPadding = PaddingValues (
89
+ horizontal = GrapesTheme .dimensions.unit16,
90
+ vertical = 0 .dp,
91
+ ),
92
+ shape = GrapesTheme .shapes.radius8,
93
+ enabled = enabled,
94
+ colors = ButtonColors (
95
+ contentColor = GrapesTheme .colors.contentBrandDefault,
96
+ containerColor = GrapesTheme .colors.backgroundPrimaryDefault,
97
+ disabledContentColor = GrapesTheme .colors.contentDisable,
98
+ disabledContainerColor = GrapesTheme .colors.backgroundPrimaryDefault,
99
+ ),
100
+ modifier = modifier
101
+ .widthIn(min = GrapesTheme .dimensions.unit48)
102
+ .height(GrapesTheme .dimensions.unit32)
37
103
) {
38
104
Text (
39
105
text = title,
40
106
style = GrapesTheme .typography.titleS,
41
- color = GrapesTheme .colors.contentSecondaryBGSecondary,
42
- modifier = Modifier .padding(
43
- horizontal = GrapesTheme .dimensions.unit16,
44
- vertical = GrapesTheme .dimensions.unit8,
45
- ),
107
+ maxLines = 1 ,
108
+ overflow = TextOverflow .Ellipsis ,
109
+ )
110
+ }
111
+ }
112
+ }
113
+
114
+ @Preview
115
+ @Preview(fontScale = 2f )
116
+ @Composable
117
+ private fun PreviewGrapesSectionWithAction () {
118
+ GrapesTheme {
119
+ GrapesSection (
120
+ title = " Some section title" ,
121
+ action = {
122
+ Action (
123
+ title = " Actionable" ,
124
+ onClick = {},
125
+ enabled = true ,
126
+ )
127
+ },
128
+ ) {
129
+ Slot (
130
+ modifier = Modifier
131
+ .fillMaxWidth()
132
+ .height(100 .dp)
133
+ )
134
+ }
135
+ }
136
+ }
137
+
138
+ @Preview
139
+ @Composable
140
+ private fun PreviewGrapesSectionWithActionDisabled () {
141
+ GrapesTheme {
142
+ GrapesSection (
143
+ title = " Some section title" ,
144
+ action = {
145
+ Action (
146
+ title = " Actionable" ,
147
+ onClick = {},
148
+ enabled = false ,
149
+ )
150
+ },
151
+ ) {
152
+ Slot (
153
+ modifier = Modifier
154
+ .fillMaxWidth()
155
+ .height(100 .dp)
46
156
)
47
- content()
48
157
}
49
158
}
50
159
}
51
160
52
161
@Preview
53
162
@Composable
54
- private fun GrapesSectionPreview () {
163
+ private fun PreviewGrapesSectionWithoutAction () {
55
164
GrapesTheme {
56
165
GrapesSection (
57
- title = " Title" ,
166
+ title = " Some section title" ,
167
+ action = null ,
58
168
) {
59
169
Slot (
60
170
modifier = Modifier
0 commit comments