14
14
* limitations under the License.
15
15
*/
16
16
17
+ @file:Suppress(" NOTHING_TO_INLINE" )
18
+
17
19
package androidx.ui.material
18
20
19
21
import androidx.compose.Composable
20
- import androidx.compose.Immutable
21
22
import androidx.ui.core.CurrentTextStyleProvider
22
23
import androidx.ui.core.Modifier
23
24
import androidx.ui.core.Text
@@ -35,63 +36,72 @@ import androidx.ui.unit.Dp
35
36
import androidx.ui.unit.dp
36
37
37
38
/* *
38
- * Styling configuration for a [Button].
39
- *
40
- * The three basic Material button styles are provided by [ContainedButtonStyle], intended for high
41
- * emphasis buttons, [OutlinedButtonStyle], intended for medium emphasis buttons, and
42
- * [TextButtonStyle], intended for low emphasis buttons.
43
- *
44
- * @param backgroundColor The background color. Use [Color.Transparent] to have no color
45
- * @param contentColor The preferred content color. Will be used by text and iconography
46
- * @param shape Defines the button's shape as well as its shadow
47
- * @param border Optional border to draw on top of the button
48
- * @param elevation The z-coordinate at which to place this button. This controls the size
49
- * of the shadow below the button
50
- * @param paddings The spacing values to apply internally between the container and the content
51
- */
52
- @Immutable
53
- data class ButtonStyle (
54
- val backgroundColor : Color ,
55
- val contentColor : Color ,
56
- val shape : Shape ,
57
- val border : Border ? = null ,
58
- val elevation : Dp = 0 .dp,
59
- val paddings : EdgeInsets = ButtonPaddings
60
- )
61
-
62
- /* *
63
- * Style used to configure a Button to look like a
39
+ * Material Design implementation of a
64
40
* [Material Contained Button](https://material.io/design/components/buttons.html#contained-button).
65
41
*
66
42
* Contained buttons are high-emphasis, distinguished by their use of elevation and fill. They
67
43
* contain actions that are primary to your app.
68
44
*
69
- * @sample androidx.ui.material.samples.ContainedButtonSample
45
+ * To make a button clickable, you must provide an onClick. If no onClick is provided, this button
46
+ * will display itself as disabled.
47
+ *
48
+ * The default text style for internal [Text] components will be set to [Typography.button]. Text
49
+ * color will try to match the correlated color for the background color. For example if the
50
+ * background color is set to [ColorPalette.primary] then the text will by default use
51
+ * [ColorPalette.onPrimary].
70
52
*
71
- * @see OutlinedButtonStyle
72
- * @see TextButtonStyle
53
+ * @sample androidx.ui.material.samples.ButtonSample
73
54
*
74
- * @param backgroundColor The background color
55
+ * @param modifier Modifier to be applied to the button.
56
+ * @param onClick Will be called when the user clicks the button. The button will be disabled if it
57
+ * is null.
58
+ * @param backgroundColor The background color. Use [Color.Transparent] to have no color
75
59
* @param contentColor The preferred content color. Will be used by text and iconography
76
60
* @param shape Defines the button's shape as well as its shadow
61
+ * @param border Border to draw around the button
77
62
* @param elevation The z-coordinate at which to place this button. This controls the size
78
63
* of the shadow below the button
64
+ * @param paddings The spacing values to apply internally between the container and the content
79
65
*/
80
66
@Composable
81
- fun ContainedButtonStyle (
67
+ fun Button (
68
+ modifier : Modifier = Modifier .None ,
69
+ onClick : (() -> Unit )? = null,
82
70
backgroundColor : Color = MaterialTheme .colors().primary,
83
71
contentColor : Color = contentColorFor(backgroundColor),
84
72
shape : Shape = MaterialTheme .shapes().button,
85
- elevation : Dp = 2.dp
86
- ) = ButtonStyle (
87
- backgroundColor = backgroundColor,
88
- shape = shape,
89
- elevation = elevation,
90
- contentColor = contentColor
91
- )
73
+ border : Border ? = null,
74
+ elevation : Dp = 2.dp,
75
+ paddings : EdgeInsets = ButtonPaddings ,
76
+ children : @Composable() () -> Unit
77
+ ) {
78
+ // Since we're adding layouts in between the clickable layer and the content, we need to
79
+ // merge all descendants, or we'll get multiple nodes
80
+ Semantics (container = true , mergeAllDescendants = true ) {
81
+ Surface (
82
+ shape = shape,
83
+ color = backgroundColor,
84
+ contentColor = contentColor,
85
+ border = border,
86
+ elevation = elevation,
87
+ modifier = modifier
88
+ ) {
89
+ Ripple (bounded = true , enabled = onClick != null ) {
90
+ Clickable (onClick = onClick) {
91
+ Container (constraints = ButtonConstraints , padding = paddings) {
92
+ CurrentTextStyleProvider (
93
+ value = MaterialTheme .typography().button,
94
+ children = children
95
+ )
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
92
102
93
103
/* *
94
- * Style used to configure a Button to look like a
104
+ * Material Design implementation of a
95
105
* [Material Outlined Button](https://material.io/design/components/buttons.html#outlined-button).
96
106
*
97
107
* Outlined buttons are medium-emphasis buttons. They contain actions that are important, but are
@@ -100,156 +110,125 @@ fun ContainedButtonStyle(
100
110
* Outlined buttons are also a lower emphasis alternative to contained buttons, or a higher emphasis
101
111
* alternative to text buttons.
102
112
*
103
- * @sample androidx.ui.material.samples.OutlinedButtonSample
113
+ * To make a button clickable, you must provide an onClick. If no onClick is provided, this button
114
+ * will display itself as disabled.
104
115
*
105
- * @see ContainedButtonStyle
106
- * @see TextButtonStyle
116
+ * The default text style for internal [Text] components will be set to [Typography.button]. Text
117
+ * color will try to match the correlated color for the background color. For example if the
118
+ * background color is set to [ColorPalette.primary] then the text will by default use
119
+ * [ColorPalette.onPrimary].
120
+ *
121
+ * @sample androidx.ui.material.samples.OutlinedButtonSample
107
122
*
108
- * @param border Optional border to draw on top of the button
109
- * @param backgroundColor The background color. Provide [Color.Transparent] to have no color.
110
- * @param contentColor The preferred content color. Will be used by text and iconography.
111
- * @param shape Defines the Button's shape.
123
+ * @param modifier Modifier to be applied to the button.
124
+ * @param onClick Will be called when the user clicks the button. The button will be disabled if it
125
+ * is null.
126
+ * @param backgroundColor The background color. Use [Color.Transparent] to have no color
127
+ * @param contentColor The preferred content color. Will be used by text and iconography
128
+ * @param shape Defines the button's shape as well as its shadow
129
+ * @param border Border to draw around the button
112
130
* @param elevation The z-coordinate at which to place this button. This controls the size
113
- * of the shadow below the button.
131
+ * of the shadow below the button
132
+ * @param paddings The spacing values to apply internally between the container and the content
114
133
*/
115
134
@Composable
116
- fun OutlinedButtonStyle (
117
- border : Border =
118
- Border (1.dp, MaterialTheme .colors().onSurface.copy(alpha = OutlinedStrokeOpacity )) ,
135
+ inline fun OutlinedButton (
136
+ modifier : Modifier = Modifier . None ,
137
+ noinline onClick : (() -> Unit ) ? = null ,
119
138
backgroundColor : Color = MaterialTheme .colors().surface,
120
139
contentColor : Color = MaterialTheme .colors().primary,
121
140
shape : Shape = MaterialTheme .shapes().button,
122
- elevation : Dp = 0.dp
123
- ) = ButtonStyle (
141
+ border : Border ? =
142
+ Border (1.dp, MaterialTheme .colors().onSurface.copy(alpha = OutlinedStrokeOpacity )),
143
+ elevation : Dp = 0.dp,
144
+ paddings : EdgeInsets = ButtonPaddings ,
145
+ noinline children : @Composable() () -> Unit
146
+ ) = Button (
147
+ modifier = modifier,
148
+ onClick = onClick,
124
149
backgroundColor = backgroundColor,
150
+ contentColor = contentColor,
125
151
shape = shape,
126
152
border = border,
127
153
elevation = elevation,
128
- contentColor = contentColor
154
+ paddings = paddings,
155
+ children = children
129
156
)
130
157
131
158
/* *
132
- * Style used to configure a Button to look like a
159
+ * Material Design implementation of a
133
160
* [Material Text Button](https://material.io/design/components/buttons.html#text-button).
134
161
*
135
162
* Text buttons are typically used for less-pronounced actions, including those located in cards and
136
163
* dialogs.
137
164
*
138
- * @sample androidx.ui.material.samples.TextButtonSample
165
+ * To make a button clickable, you must provide an onClick. If no onClick is provided, this button
166
+ * will display itself as disabled.
139
167
*
140
- * @see ContainedButtonStyle
141
- * @see OutlinedButtonStyle
168
+ * The default text style for internal [Text] components will be set to [Typography.button]. Text
169
+ * color will try to match the correlated color for the background color. For example if the
170
+ * background color is set to [ColorPalette.primary] then the text will by default use
171
+ * [ColorPalette.onPrimary].
142
172
*
143
- * @param shape Defines the Button's shape.
144
- * @param contentColor The preferred content color. Will be used by text and iconography.
145
- */
146
- @Composable
147
- fun TextButtonStyle (
148
- shape : Shape = MaterialTheme .shapes().button,
149
- contentColor : Color = MaterialTheme .colors().primary
150
- ) = ButtonStyle (
151
- backgroundColor = Color .Transparent ,
152
- shape = shape,
153
- paddings = TextButtonPaddings ,
154
- contentColor = contentColor
155
- )
156
-
157
- /* *
158
- * Material Design implementation of [Button](https://material.io/design/components/buttons.html).
159
- *
160
- * To make a button clickable, you must provide an onClick. If no onClick is provided, this button will display
161
- * itself as disabled.
162
- *
163
- * The default text style for internal [Text] components will be set to [Typography.button]. Text color will
164
- * try to match the correlated color for the background color. For example if the background color is set to
165
- * [ColorPalette.primary] then the text will by default use [ColorPalette.onPrimary].
166
- *
167
- * @sample androidx.ui.material.samples.ButtonSample
168
- *
169
- * @param modifier Modifier to be applied to the button.
170
- * @param onClick Will be called when the user clicks the button. The button will be disabled if it is null.
171
- * @param style Contains the styling parameters for the button.
172
- */
173
- @Composable
174
- fun Button (
175
- modifier : Modifier = Modifier .None ,
176
- onClick : (() -> Unit )? = null,
177
- style : ButtonStyle = ContainedButtonStyle (),
178
- children : @Composable() () -> Unit
179
- ) {
180
- // Since we're adding layouts in between the clickable layer and the content, we need to
181
- // merge all descendants, or we'll get multiple nodes
182
- Semantics (container = true , mergeAllDescendants = true ) {
183
- Surface (
184
- shape = style.shape,
185
- color = style.backgroundColor,
186
- contentColor = style.contentColor,
187
- border = style.border,
188
- elevation = style.elevation,
189
- modifier = modifier
190
- ) {
191
- Ripple (bounded = true , enabled = onClick != null ) {
192
- Clickable (onClick = onClick) {
193
- Container (constraints = ButtonConstraints , padding = style.paddings) {
194
- CurrentTextStyleProvider (
195
- value = MaterialTheme .typography().button,
196
- children = children
197
- )
198
- }
199
- }
200
- }
201
- }
202
- }
203
- }
204
-
205
- /* *
206
- * Material Design implementation of [Button](https://material.io/design/components/buttons.html) that contains some
207
- * text.
208
- *
209
- * To make a button clickable, you must provide an onClick. If no onClick is provided, this button will display
210
- * itself as disabled.
211
- *
212
- * The default text style for internal [Text] components will be set to [Typography.button]. Text color will
213
- * try to match the correlated color for the background color. For example if the background color is set to
214
- * [ColorPalette.primary] then the text will by default use [ColorPalette.onPrimary].
215
- *
216
- * @sample androidx.ui.material.samples.ButtonWithTextSample
217
- *
218
- * There is a different overload for this component that takes a lambda of customizable content.
173
+ * @sample androidx.ui.material.samples.TextButtonSample
219
174
*
220
- * @param text The text to display.
221
175
* @param modifier Modifier to be applied to the button.
222
- * @param onClick Will be called when the user clicks the button. The button will be disabled if it is null.
223
- * @param style Contains the styling parameters for the button.
176
+ * @param onClick Will be called when the user clicks the button. The button will be disabled if it
177
+ * is null.
178
+ * @param backgroundColor The background color. Use [Color.Transparent] to have no color
179
+ * @param contentColor The preferred content color. Will be used by text and iconography
180
+ * @param shape Defines the button's shape as well as its shadow
181
+ * @param border Border to draw around the button
182
+ * @param elevation The z-coordinate at which to place this button. This controls the size
183
+ * of the shadow below the button
184
+ * @param paddings The spacing values to apply internally between the container and the content
224
185
*/
225
186
@Composable
226
- fun Button (
227
- text : String ,
187
+ inline fun TextButton (
228
188
modifier : Modifier = Modifier .None ,
229
- onClick : (() -> Unit )? = null,
230
- style : ButtonStyle = ContainedButtonStyle ()
231
- ) {
232
- Button (modifier = modifier, style = style, onClick = onClick) {
233
- Text (text = text)
234
- }
235
- }
189
+ noinline onClick : (() -> Unit )? = null,
190
+ backgroundColor : Color = Color .Transparent ,
191
+ contentColor : Color = MaterialTheme .colors().primary,
192
+ shape : Shape = MaterialTheme .shapes().button,
193
+ border : Border ? = null,
194
+ elevation : Dp = 0.dp,
195
+ paddings : EdgeInsets = TextButtonPaddings ,
196
+ noinline children : @Composable() () -> Unit
197
+ ) = Button (
198
+ modifier = modifier,
199
+ onClick = onClick,
200
+ backgroundColor = backgroundColor,
201
+ contentColor = contentColor,
202
+ shape = shape,
203
+ border = border,
204
+ elevation = elevation,
205
+ paddings = paddings,
206
+ children = children
207
+ )
236
208
237
209
// Specification for Material Button:
238
210
private val ButtonConstraints = DpConstraints (
239
211
minWidth = 64 .dp,
240
212
minHeight = 36 .dp
241
213
)
214
+
242
215
private val ButtonHorizontalPadding = 16 .dp
243
216
private val ButtonVerticalPadding = 8 .dp
244
- private val ButtonPaddings = EdgeInsets (
217
+ private val TextButtonHorizontalPadding = 8 .dp
218
+
219
+ @PublishedApi
220
+ internal val ButtonPaddings = EdgeInsets (
245
221
left = ButtonHorizontalPadding ,
246
222
top = ButtonVerticalPadding ,
247
223
right = ButtonHorizontalPadding ,
248
224
bottom = ButtonVerticalPadding
249
225
)
250
- private val TextButtonHorizontalPadding = 8 .dp
251
- private val TextButtonPaddings = ButtonPaddings .copy(
226
+
227
+ @PublishedApi
228
+ internal val TextButtonPaddings = ButtonPaddings .copy(
252
229
left = TextButtonHorizontalPadding ,
253
230
right = TextButtonHorizontalPadding
254
231
)
255
- private val OutlinedStrokeOpacity = 0.12f
232
+
233
+ @PublishedApi
234
+ internal const val OutlinedStrokeOpacity = 0.12f
0 commit comments