1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "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 * http://www.apache.org/licenses/LICENSE-2.0
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 androidx.compose.material
18
19 import androidx.compose.foundation.clickable
20 import androidx.compose.foundation.interaction.Interaction
21 import androidx.compose.foundation.interaction.MutableInteractionSource
22 import androidx.compose.foundation.layout.Box
23 import androidx.compose.foundation.selection.toggleable
24 import androidx.compose.runtime.Composable
25 import androidx.compose.runtime.CompositionLocalProvider
26 import androidx.compose.ui.Alignment
27 import androidx.compose.ui.Modifier
28 import androidx.compose.ui.semantics.Role
29 import androidx.compose.ui.unit.dp
30
31 /**
32 * IconButton is a clickable icon, used to represent actions. An IconButton has an overall minimum
33 * touch target size of 48 x 48dp, to meet accessibility guidelines. [content] is centered inside
34 * the IconButton.
35 *
36 * This component is typically used inside an App Bar for the navigation icon / actions. See App Bar
37 * documentation for samples of this.
38 *
39 * [content] should typically be an [Icon], using an icon from
40 * [androidx.compose.material.icons.Icons]. If using a custom icon, note that the typical size for
41 * the internal icon is 24 x 24 dp.
42 *
43 * @sample androidx.compose.material.samples.IconButtonSample
44 * @param onClick the lambda to be invoked when this icon is pressed
45 * @param modifier optional [Modifier] for this IconButton
46 * @param enabled whether or not this IconButton will handle input events and appear enabled for
47 * semantics purposes
48 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
49 * emitting [Interaction]s for this IconButton. You can use this to change the IconButton's
50 * appearance or preview the IconButton in different states. Note that if `null` is provided,
51 * interactions will still happen internally.
52 * @param content the content (icon) to be drawn inside the IconButton. This is typically an [Icon].
53 */
54 @Composable
IconButtonnull55 fun IconButton(
56 onClick: () -> Unit,
57 modifier: Modifier = Modifier,
58 enabled: Boolean = true,
59 interactionSource: MutableInteractionSource? = null,
60 content: @Composable () -> Unit
61 ) {
62 Box(
63 modifier =
64 modifier
65 .minimumInteractiveComponentSize()
66 .clickable(
67 onClick = onClick,
68 enabled = enabled,
69 role = Role.Button,
70 interactionSource = interactionSource,
71 indication = ripple(bounded = false, radius = RippleRadius)
72 ),
73 contentAlignment = Alignment.Center
74 ) {
75 val contentAlpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
76 CompositionLocalProvider(LocalContentAlpha provides contentAlpha, content = content)
77 }
78 }
79
80 /**
81 * An [IconButton] with two states, for icons that can be toggled 'on' and 'off', such as a bookmark
82 * icon, or a navigation icon that opens a drawer.
83 *
84 * @sample androidx.compose.material.samples.IconToggleButtonSample
85 * @param checked whether this IconToggleButton is currently checked
86 * @param onCheckedChange callback to be invoked when this icon is selected
87 * @param modifier optional [Modifier] for this IconToggleButton
88 * @param enabled enabled whether or not this [IconToggleButton] will handle input events and appear
89 * enabled for semantics purposes
90 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
91 * emitting [Interaction]s for this IconButton. You can use this to change the IconButton's
92 * appearance or preview the IconButton in different states. Note that if `null` is provided,
93 * interactions will still happen internally.
94 * @param content the content (icon) to be drawn inside the IconToggleButton. This is typically an
95 * [Icon].
96 */
97 @Composable
IconToggleButtonnull98 fun IconToggleButton(
99 checked: Boolean,
100 onCheckedChange: (Boolean) -> Unit,
101 modifier: Modifier = Modifier,
102 enabled: Boolean = true,
103 interactionSource: MutableInteractionSource? = null,
104 content: @Composable () -> Unit
105 ) {
106 Box(
107 modifier =
108 modifier
109 .minimumInteractiveComponentSize()
110 .toggleable(
111 value = checked,
112 onValueChange = onCheckedChange,
113 enabled = enabled,
114 role = Role.Checkbox,
115 interactionSource = interactionSource,
116 indication = ripple(bounded = false, radius = RippleRadius)
117 ),
118 contentAlignment = Alignment.Center
119 ) {
120 val contentAlpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
121 CompositionLocalProvider(LocalContentAlpha provides contentAlpha, content = content)
122 }
123 }
124
125 // Default radius of an unbounded ripple in an IconButton
126 private val RippleRadius = 24.dp
127