1 /*
2 * Copyright 2021 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 package androidx.compose.material3
17
18 import androidx.compose.animation.core.FiniteAnimationSpec
19 import androidx.compose.foundation.BorderStroke
20 import androidx.compose.foundation.background
21 import androidx.compose.foundation.clickable
22 import androidx.compose.foundation.interaction.Interaction
23 import androidx.compose.foundation.interaction.MutableInteractionSource
24 import androidx.compose.foundation.interaction.collectIsPressedAsState
25 import androidx.compose.foundation.layout.Box
26 import androidx.compose.foundation.layout.size
27 import androidx.compose.foundation.selection.toggleable
28 import androidx.compose.foundation.shape.CornerBasedShape
29 import androidx.compose.foundation.shape.RoundedCornerShape
30 import androidx.compose.material3.internal.childSemantics
31 import androidx.compose.material3.internal.rememberAnimatedShape
32 import androidx.compose.material3.tokens.MotionSchemeKeyTokens
33 import androidx.compose.runtime.Composable
34 import androidx.compose.runtime.CompositionLocalProvider
35 import androidx.compose.runtime.Immutable
36 import androidx.compose.runtime.Stable
37 import androidx.compose.runtime.State
38 import androidx.compose.runtime.getValue
39 import androidx.compose.runtime.key
40 import androidx.compose.runtime.remember
41 import androidx.compose.runtime.rememberUpdatedState
42 import androidx.compose.ui.Alignment
43 import androidx.compose.ui.Modifier
44 import androidx.compose.ui.draw.clip
45 import androidx.compose.ui.graphics.Color
46 import androidx.compose.ui.graphics.Shape
47 import androidx.compose.ui.graphics.takeOrElse
48 import androidx.compose.ui.semantics.Role
49 import androidx.compose.ui.semantics.role
50 import androidx.compose.ui.semantics.semantics
51
52 /**
53 * [Material Design standard icon button](https://m3.material.io/components/icon-button/overview)
54 *
55 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
56 * compact button is required, such as in a toolbar or image list.
57 *
58 * 
60 *
61 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
62 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
63 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
64 *
65 * Simple Usage
66 *
67 * @sample androidx.compose.material3.samples.IconButtonSample
68 *
69 * IconButton with a color tint
70 *
71 * @sample androidx.compose.material3.samples.TintedIconButtonSample
72 * @param onClick called when this icon button is clicked
73 * @param modifier the [Modifier] to be applied to this icon button
74 * @param enabled controls the enabled state of this icon button. When `false`, this component will
75 * not respond to user input, and it will appear visually disabled and disabled to accessibility
76 * services.
77 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
78 * button in different states. See [IconButtonDefaults.iconButtonVibrantColors].
79 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
80 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
81 * appearance or preview the icon button in different states. Note that if `null` is provided,
82 * interactions will still happen internally.
83 * @param content the content of this icon button, typically an [Icon]
84 */
85 @Deprecated(
86 message = "Use overload with `shape`",
87 replaceWith =
88 ReplaceWith(
89 "IconButton(onClick, modifier, enabled, colors, interactionSource, shape, content)"
90 ),
91 level = DeprecationLevel.HIDDEN
92 )
93 @Composable
IconButtonnull94 fun IconButton(
95 onClick: () -> Unit,
96 modifier: Modifier = Modifier,
97 enabled: Boolean = true,
98 colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
99 interactionSource: MutableInteractionSource? = null,
100 content: @Composable () -> Unit
101 ) {
102 IconButton(
103 onClick,
104 modifier,
105 enabled,
106 colors,
107 interactionSource,
108 IconButtonDefaults.standardShape,
109 content
110 )
111 }
112
113 /**
114 * [Material Design standard icon button](https://m3.material.io/components/icon-button/overview)
115 *
116 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
117 * compact button is required, such as in a toolbar or image list.
118 *
119 * 
121 *
122 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
123 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
124 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
125 *
126 * Simple Usage
127 *
128 * @sample androidx.compose.material3.samples.IconButtonSample
129 *
130 * IconButton with a color tint
131 *
132 * @sample androidx.compose.material3.samples.TintedIconButtonSample
133 *
134 * Small-sized narrow round shape IconButton
135 *
136 * @sample androidx.compose.material3.samples.ExtraSmallNarrowSquareIconButtonsSample
137 *
138 * Medium / default size round-shaped icon button
139 *
140 * @sample androidx.compose.material3.samples.MediumRoundWideIconButtonSample
141 * @param onClick called when this icon button is clicked
142 * @param modifier the [Modifier] to be applied to this icon button
143 * @param enabled controls the enabled state of this icon button. When `false`, this component will
144 * not respond to user input, and it will appear visually disabled and disabled to accessibility
145 * services.
146 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
147 * button in different states. See [IconButtonDefaults.iconButtonVibrantColors] and
148 * [IconButtonDefaults.iconButtonColors] .
149 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
150 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
151 * appearance or preview the icon button in different states. Note that if `null` is provided,
152 * interactions will still happen internally.
153 * @param shape the [Shape] of this icon button.
154 * @param content the content of this icon button, typically an [Icon]
155 */
156 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
157 @Composable
IconButtonnull158 fun IconButton(
159 onClick: () -> Unit,
160 modifier: Modifier = Modifier,
161 enabled: Boolean = true,
162 colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
163 interactionSource: MutableInteractionSource? = null,
164 shape: Shape = IconButtonDefaults.standardShape,
165 content: @Composable () -> Unit
166 ) =
167 IconButtonImpl(
168 onClick = onClick,
169 modifier = modifier,
170 enabled = enabled,
171 colors = colors,
172 interactionSource = interactionSource,
173 shape = shape,
174 content = content
175 )
176
177 /**
178 * [Material Design standard icon button](https://m3.material.io/components/icon-button/overview)
179 *
180 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
181 * compact button is required, such as in a toolbar or image list.
182 *
183 * 
185 *
186 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
187 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
188 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
189 *
190 * Simple Usage
191 *
192 * @sample androidx.compose.material3.samples.IconButtonWithAnimatedShapeSample
193 * @param onClick called when this icon button is clicked
194 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
195 * user's interaction with the icon button.
196 * @param modifier the [Modifier] to be applied to this icon button
197 * @param enabled controls the enabled state of this icon button. When `false`, this component will
198 * not respond to user input, and it will appear visually disabled and disabled to accessibility
199 * services.
200 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
201 * button in different states. See [IconButtonDefaults.iconButtonVibrantColors] and
202 * [IconButtonDefaults.iconButtonColors] .
203 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
204 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
205 * appearance or preview the icon button in different states. Note that if `null` is provided,
206 * interactions will still happen internally.
207 * @param content the content of this icon button, typically an [Icon]
208 */
209 @ExperimentalMaterial3ExpressiveApi
210 @Composable
211 fun IconButton(
212 onClick: () -> Unit,
213 shapes: IconButtonShapes,
214 modifier: Modifier = Modifier,
215 enabled: Boolean = true,
216 colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
217 interactionSource: MutableInteractionSource? = null,
218 content: @Composable () -> Unit
219 ) {
220 @Suppress("NAME_SHADOWING")
221 val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
222 IconButtonImpl(
223 modifier,
224 onClick = onClick,
225 enabled = enabled,
226 shape = shapeForInteraction(shapes, interactionSource),
227 colors = colors,
228 interactionSource = interactionSource,
229 content = content
230 )
231 }
232
233 @ExperimentalMaterial3ExpressiveApi
234 @Composable
IconButtonImplnull235 private fun IconButtonImpl(
236 modifier: Modifier,
237 onClick: () -> Unit,
238 enabled: Boolean,
239 shape: Shape,
240 colors: IconButtonColors,
241 interactionSource: MutableInteractionSource?,
242 content: @Composable () -> Unit
243 ) {
244 @Suppress("NAME_SHADOWING")
245 val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
246 Box(
247 modifier =
248 modifier
249 .minimumInteractiveComponentSize()
250 .size(IconButtonDefaults.smallContainerSize())
251 .clip(shape)
252 .background(color = colors.containerColor(enabled), shape = shape)
253 .clickable(
254 onClick = onClick,
255 enabled = enabled,
256 role = Role.Button,
257 interactionSource = interactionSource,
258 indication = ripple()
259 )
260 .childSemantics(),
261 contentAlignment = Alignment.Center
262 ) {
263 val contentColor = colors.contentColor(enabled)
264 CompositionLocalProvider(LocalContentColor provides contentColor, content = content)
265 }
266 }
267
268 /**
269 * [Material Design standard icon toggle
270 * button](https://m3.material.io/components/icon-button/overview)
271 *
272 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
273 * compact button is required, such as in a toolbar or image list.
274 *
275 * 
277 *
278 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
279 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
280 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
281 *
282 * @sample androidx.compose.material3.samples.IconToggleButtonSample
283 * @param checked whether this icon button is toggled on or off
284 * @param onCheckedChange called when this icon button is clicked
285 * @param modifier the [Modifier] to be applied to this icon button
286 * @param enabled controls the enabled state of this icon button. When `false`, this component will
287 * not respond to user input, and it will appear visually disabled and disabled to accessibility
288 * services.
289 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
290 * button in different states. See [IconButtonDefaults.iconToggleButtonVibrantColors].
291 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
292 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
293 * appearance or preview the icon button in different states. Note that if `null` is provided,
294 * interactions will still happen internally.
295 * @param content the content of this icon button, typically an [Icon]
296 */
297 @Deprecated(
298 message = "Use overload with `shape`",
299 replaceWith =
300 ReplaceWith(
301 "IconToggleButton(checked, onCheckedChange, modifier, enabled, colors," +
302 " interactionSource, shape, content)"
303 ),
304 level = DeprecationLevel.HIDDEN
305 )
306 @Composable
IconToggleButtonnull307 fun IconToggleButton(
308 checked: Boolean,
309 onCheckedChange: (Boolean) -> Unit,
310 modifier: Modifier = Modifier,
311 enabled: Boolean = true,
312 colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonColors(),
313 interactionSource: MutableInteractionSource? = null,
314 content: @Composable () -> Unit
315 ) {
316 IconToggleButton(
317 checked,
318 onCheckedChange,
319 modifier,
320 enabled,
321 colors,
322 interactionSource,
323 IconButtonDefaults.standardShape,
324 content
325 )
326 }
327
328 /**
329 * [Material Design standard icon toggle
330 * button](https://m3.material.io/components/icon-button/overview)
331 *
332 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
333 * compact button is required, such as in a toolbar or image list.
334 *
335 * 
337 *
338 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
339 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
340 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
341 *
342 * @sample androidx.compose.material3.samples.IconToggleButtonSample
343 * @param checked whether this icon button is toggled on or off
344 * @param onCheckedChange called when this icon button is clicked
345 * @param modifier the [Modifier] to be applied to this icon button
346 * @param enabled controls the enabled state of this icon button. When `false`, this component will
347 * not respond to user input, and it will appear visually disabled and disabled to accessibility
348 * services.
349 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
350 * button in different states. See [IconButtonDefaults.iconToggleButtonVibrantColors] and
351 * [IconButtonDefaults.iconToggleButtonColors].
352 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
353 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
354 * appearance or preview the icon button in different states. Note that if `null` is provided,
355 * interactions will still happen internally.
356 * @param shape the [Shape] of this icon button.
357 * @param content the content of this icon button, typically an [Icon]
358 */
359 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
360 @Composable
IconToggleButtonnull361 fun IconToggleButton(
362 checked: Boolean,
363 onCheckedChange: (Boolean) -> Unit,
364 modifier: Modifier = Modifier,
365 enabled: Boolean = true,
366 colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonColors(),
367 interactionSource: MutableInteractionSource? = null,
368 shape: Shape = IconButtonDefaults.standardShape,
369 content: @Composable () -> Unit
370 ) =
371 IconToggleButtonImpl(
372 checked = checked,
373 onCheckedChange = onCheckedChange,
374 modifier = modifier,
375 enabled = enabled,
376 colors = colors,
377 interactionSource = interactionSource,
378 shape = shape,
379 content = content
380 )
381
382 /**
383 * [Material Design standard icon toggle
384 * button](https://m3.material.io/components/icon-button/overview)
385 *
386 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
387 * compact button is required, such as in a toolbar or image list.
388 *
389 * 
391 *
392 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
393 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
394 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
395 *
396 * @sample androidx.compose.material3.samples.IconToggleButtonWithAnimatedShapeSample
397 * @param checked whether this button is toggled on or off
398 * @param onCheckedChange called when this icon button is clicked
399 * @param shapes the [IconToggleButtonShapes] that the icon toggle button will morph between
400 * depending on the user's interaction with this button.
401 * @param modifier the [Modifier] to be applied to this icon button
402 * @param enabled controls the enabled state of this icon button. When `false`, this component will
403 * not respond to user input, and it will appear visually disabled and disabled to accessibility
404 * services.
405 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
406 * button in different states. See [IconButtonDefaults.iconToggleButtonVibrantColors].
407 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
408 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
409 * appearance or preview the icon button in different states. Note that if `null` is provided,
410 * interactions will still happen internally.
411 * @param content the content of this icon button, typically an [Icon]
412 */
413 @ExperimentalMaterial3ExpressiveApi
414 @Composable
415 fun IconToggleButton(
416 checked: Boolean,
417 onCheckedChange: (Boolean) -> Unit,
418 shapes: IconToggleButtonShapes,
419 modifier: Modifier = Modifier,
420 enabled: Boolean = true,
421 colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonVibrantColors(),
422 interactionSource: MutableInteractionSource? = null,
423 content: @Composable () -> Unit
424 ) {
425 @Suppress("NAME_SHADOWING")
426 val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
427 IconToggleButtonImpl(
428 checked = checked,
429 onCheckedChange = onCheckedChange,
430 modifier = modifier,
431 enabled = enabled,
432 shape = shapeForInteraction(checked, shapes, interactionSource),
433 colors = colors,
434 interactionSource = interactionSource,
435 content = content
436 )
437 }
438
439 @ExperimentalMaterial3ExpressiveApi
440 @Composable
IconToggleButtonImplnull441 private fun IconToggleButtonImpl(
442 checked: Boolean,
443 onCheckedChange: (Boolean) -> Unit,
444 modifier: Modifier = Modifier,
445 enabled: Boolean = true,
446 colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonVibrantColors(),
447 interactionSource: MutableInteractionSource? = null,
448 shape: Shape = IconButtonDefaults.standardShape,
449 content: @Composable () -> Unit
450 ) {
451 @Suppress("NAME_SHADOWING")
452 val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
453 Box(
454 modifier =
455 modifier
456 .minimumInteractiveComponentSize()
457 .size(IconButtonDefaults.smallContainerSize())
458 .clip(shape)
459 .background(color = colors.containerColor(enabled, checked).value)
460 .toggleable(
461 value = checked,
462 onValueChange = onCheckedChange,
463 enabled = enabled,
464 role = Role.Checkbox,
465 interactionSource = interactionSource,
466 indication = ripple()
467 ),
468 contentAlignment = Alignment.Center
469 ) {
470 val contentColor = colors.contentColor(enabled, checked).value
471 CompositionLocalProvider(LocalContentColor provides contentColor, content = content)
472 }
473 }
474
475 /**
476 * [Material Design filled icon button](https://m3.material.io/components/icon-button/overview)
477 *
478 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
479 * compact button is required, such as in a toolbar or image list.
480 *
481 * 
483 *
484 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
485 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
486 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
487 *
488 * Filled icon button sample:
489 *
490 * @sample androidx.compose.material3.samples.FilledIconButtonSample
491 * @param onClick called when this icon button is clicked
492 * @param modifier the [Modifier] to be applied to this icon button
493 * @param enabled controls the enabled state of this icon button. When `false`, this component will
494 * not respond to user input, and it will appear visually disabled and disabled to accessibility
495 * services.
496 * @param shape defines the shape of this icon button's container
497 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
498 * button in different states. See [IconButtonDefaults.filledIconButtonColors].
499 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
500 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
501 * appearance or preview the icon button in different states. Note that if `null` is provided,
502 * interactions will still happen internally.
503 * @param content the content of this icon button, typically an [Icon]
504 */
505 @Composable
FilledIconButtonnull506 fun FilledIconButton(
507 onClick: () -> Unit,
508 modifier: Modifier = Modifier,
509 enabled: Boolean = true,
510 shape: Shape = IconButtonDefaults.filledShape,
511 colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors(),
512 interactionSource: MutableInteractionSource? = null,
513 content: @Composable () -> Unit
514 ) =
515 SurfaceIconButton(
516 onClick = onClick,
517 modifier = modifier,
518 enabled = enabled,
519 shape = shape,
520 colors = colors,
521 border = null,
522 interactionSource = interactionSource,
523 content = content
524 )
525
526 /**
527 * [Material Design filled icon button](https://m3.material.io/components/icon-button/overview)
528 *
529 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
530 * compact button is required, such as in a toolbar or image list.
531 *
532 * 
534 *
535 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
536 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
537 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
538 *
539 * Filled icon button sample:
540 *
541 * @sample androidx.compose.material3.samples.FilledIconButtonWithAnimatedShapeSample
542 * @param onClick called when this icon button is clicked
543 * @param modifier the [Modifier] to be applied to this icon button
544 * @param enabled controls the enabled state of this icon button. When `false`, this component will
545 * not respond to user input, and it will appear visually disabled and disabled to accessibility
546 * services.
547 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
548 * user's interaction with the icon button.
549 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
550 * button in different states. See [IconButtonDefaults.filledIconButtonColors].
551 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
552 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
553 * appearance or preview the icon button in different states. Note that if `null` is provided,
554 * interactions will still happen internally.
555 * @param content the content of this icon button, typically an [Icon]
556 */
557 @ExperimentalMaterial3ExpressiveApi
558 @Composable
559 fun FilledIconButton(
560 onClick: () -> Unit,
561 shapes: IconButtonShapes,
562 modifier: Modifier = Modifier,
563 enabled: Boolean = true,
564 colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors(),
565 interactionSource: MutableInteractionSource? = null,
566 content: @Composable () -> Unit
567 ) =
568 SurfaceIconButton(
569 onClick = onClick,
570 modifier = modifier,
571 enabled = enabled,
572 shapes = shapes,
573 colors = colors,
574 border = null,
575 interactionSource = interactionSource,
576 content = content
577 )
578
579 /**
580 * [Material Design filled icon button](https://m3.material.io/components/icon-button/overview)
581 *
582 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
583 * compact button is required, such as in a toolbar or image list.
584 *
585 * 
587 *
588 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
589 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
590 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
591 *
592 * Toggleable filled icon button sample:
593 *
594 * @sample androidx.compose.material3.samples.FilledIconToggleButtonSample
595 * @param checked whether this icon button is toggled on or off
596 * @param onCheckedChange called when this icon button is clicked
597 * @param modifier the [Modifier] to be applied to this icon button
598 * @param enabled controls the enabled state of this icon button. When `false`, this component will
599 * not respond to user input, and it will appear visually disabled and disabled to accessibility
600 * services.
601 * @param shape defines the shape of this icon button's container
602 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
603 * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors].
604 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
605 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
606 * appearance or preview the icon button in different states. Note that if `null` is provided,
607 * interactions will still happen internally.
608 * @param content the content of this icon button, typically an [Icon]
609 */
610 @Composable
611 fun FilledIconToggleButton(
612 checked: Boolean,
613 onCheckedChange: (Boolean) -> Unit,
614 modifier: Modifier = Modifier,
615 enabled: Boolean = true,
616 shape: Shape = IconButtonDefaults.filledShape,
617 colors: IconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(),
618 interactionSource: MutableInteractionSource? = null,
619 content: @Composable () -> Unit
620 ) =
621 SurfaceIconToggleButton(
622 checked = checked,
623 onCheckedChange = onCheckedChange,
624 modifier = modifier.semantics { role = Role.Checkbox },
625 enabled = enabled,
626 shape = shape,
627 colors = colors,
628 border = null,
629 interactionSource = interactionSource,
630 content = content
631 )
632
633 /**
634 * [Material Design filled icon toggle
635 * button](https://m3.material.io/components/icon-button/overview)
636 *
637 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
638 * compact button is required, such as in a toolbar or image list.
639 *
640 * 
642 *
643 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
644 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
645 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
646 *
647 * Toggleable filled icon button sample:
648 *
649 * @sample androidx.compose.material3.samples.FilledIconToggleButtonWithAnimatedShapeSample
650 * @param checked whether this icon button is toggled on or off
651 * @param onCheckedChange called when this icon button is clicked
652 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
653 * user's interaction with the icon button.
654 * @param modifier the [Modifier] to be applied to this icon button
655 * @param enabled controls the enabled state of this icon button. When `false`, this component will
656 * not respond to user input, and it will appear visually disabled and disabled to accessibility
657 * services.
658 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
659 * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors].
660 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
661 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
662 * appearance or preview the icon button in different states. Note that if `null` is provided,
663 * interactions will still happen internally.
664 * @param content the content of this icon button, typically an [Icon]
665 */
666 @ExperimentalMaterial3ExpressiveApi
667 @Composable
FilledIconToggleButtonnull668 fun FilledIconToggleButton(
669 checked: Boolean,
670 onCheckedChange: (Boolean) -> Unit,
671 shapes: IconToggleButtonShapes,
672 modifier: Modifier = Modifier,
673 enabled: Boolean = true,
674 colors: IconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(),
675 interactionSource: MutableInteractionSource? = null,
676 content: @Composable () -> Unit
677 ) =
678 SurfaceIconToggleButton(
679 checked = checked,
680 onCheckedChange = onCheckedChange,
681 modifier = modifier.semantics { role = Role.Checkbox },
682 enabled = enabled,
683 shapes = shapes,
684 colors = colors,
685 border = null,
686 interactionSource = interactionSource,
687 content = content
688 )
689
690 /**
691 * [Material Design filled tonal icon
692 * button](https://m3.material.io/components/icon-button/overview)
693 *
694 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
695 * compact button is required, such as in a toolbar or image list.
696 *
697 * 
699 *
700 * A filled tonal icon button is a medium-emphasis icon button that is an alternative middle ground
701 * between the default [FilledIconButton] and [OutlinedIconButton]. They can be used in contexts
702 * where the lower-priority icon button requires slightly more emphasis than an outline would give.
703 *
704 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
705 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
706 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
707 *
708 * Filled tonal icon button sample:
709 *
710 * @sample androidx.compose.material3.samples.FilledTonalIconButtonSample
711 * @param onClick called when this icon button is clicked
712 * @param modifier the [Modifier] to be applied to this icon button
713 * @param enabled controls the enabled state of this icon button. When `false`, this component will
714 * not respond to user input, and it will appear visually disabled and disabled to accessibility
715 * services.
716 * @param shape defines the shape of this icon button's container
717 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
718 * button in different states. See [IconButtonDefaults.filledIconButtonColors].
719 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
720 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
721 * appearance or preview the icon button in different states. Note that if `null` is provided,
722 * interactions will still happen internally.
723 * @param content the content of this icon button, typically an [Icon]
724 */
725 @Composable
FilledTonalIconButtonnull726 fun FilledTonalIconButton(
727 onClick: () -> Unit,
728 modifier: Modifier = Modifier,
729 enabled: Boolean = true,
730 shape: Shape = IconButtonDefaults.filledShape,
731 colors: IconButtonColors = IconButtonDefaults.filledTonalIconButtonColors(),
732 interactionSource: MutableInteractionSource? = null,
733 content: @Composable () -> Unit
734 ) =
735 SurfaceIconButton(
736 onClick = onClick,
737 modifier = modifier,
738 enabled = enabled,
739 shape = shape,
740 colors = colors,
741 border = null,
742 interactionSource = interactionSource,
743 content = content
744 )
745
746 /**
747 * [Material Design filled tonal icon
748 * button](https://m3.material.io/components/icon-button/overview)
749 *
750 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
751 * compact button is required, such as in a toolbar or image list.
752 *
753 * 
755 *
756 * A filled tonal icon button is a medium-emphasis icon button that is an alternative middle ground
757 * between the default [FilledIconButton] and [OutlinedIconButton]. They can be used in contexts
758 * where the lower-priority icon button requires slightly more emphasis than an outline would give.
759 *
760 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
761 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
762 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
763 *
764 * Filled tonal icon button sample:
765 *
766 * @sample androidx.compose.material3.samples.FilledTonalIconButtonWithAnimatedShapeSample
767 * @param onClick called when this icon button is clicked
768 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
769 * user's interaction with the icon button.
770 * @param modifier the [Modifier] to be applied to this icon button
771 * @param enabled controls the enabled state of this icon button. When `false`, this component will
772 * not respond to user input, and it will appear visually disabled and disabled to accessibility
773 * services.
774 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
775 * button in different states. See [IconButtonDefaults.filledIconButtonColors].
776 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
777 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
778 * appearance or preview the icon button in different states. Note that if `null` is provided,
779 * interactions will still happen internally.
780 * @param content the content of this icon button, typically an [Icon]
781 */
782 @ExperimentalMaterial3ExpressiveApi
783 @Composable
784 fun FilledTonalIconButton(
785 onClick: () -> Unit,
786 shapes: IconButtonShapes,
787 modifier: Modifier = Modifier,
788 enabled: Boolean = true,
789 colors: IconButtonColors = IconButtonDefaults.filledTonalIconButtonColors(),
790 interactionSource: MutableInteractionSource? = null,
791 content: @Composable () -> Unit
792 ) =
793 SurfaceIconButton(
794 onClick = onClick,
795 modifier = modifier,
796 enabled = enabled,
797 shapes = shapes,
798 colors = colors,
799 border = null,
800 interactionSource = interactionSource,
801 content = content
802 )
803
804 /**
805 * [Material Design filled tonal icon toggle
806 * button](https://m3.material.io/components/icon-button/overview)
807 *
808 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
809 * compact button is required, such as in a toolbar or image list.
810 *
811 * 
813 *
814 * A filled tonal toggle icon button is a medium-emphasis icon button that is an alternative middle
815 * ground between the default [FilledIconToggleButton] and [OutlinedIconToggleButton]. They can be
816 * used in contexts where the lower-priority icon button requires slightly more emphasis than an
817 * outline would give.
818 *
819 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
820 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
821 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
822 *
823 * Toggleable filled tonal icon button sample:
824 *
825 * @sample androidx.compose.material3.samples.FilledTonalIconToggleButtonSample
826 * @param checked whether this icon button is toggled on or off
827 * @param onCheckedChange called when this icon button is clicked
828 * @param modifier the [Modifier] to be applied to this icon button
829 * @param enabled controls the enabled state of this icon button. When `false`, this component will
830 * not respond to user input, and it will appear visually disabled and disabled to accessibility
831 * services.
832 * @param shape defines the shape of this icon button's container
833 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
834 * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors].
835 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
836 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
837 * appearance or preview the icon button in different states. Note that if `null` is provided,
838 * interactions will still happen internally.
839 * @param content the content of this icon button, typically an [Icon]
840 */
841 @Composable
842 fun FilledTonalIconToggleButton(
843 checked: Boolean,
844 onCheckedChange: (Boolean) -> Unit,
845 modifier: Modifier = Modifier,
846 enabled: Boolean = true,
847 shape: Shape = IconButtonDefaults.filledShape,
848 colors: IconToggleButtonColors = IconButtonDefaults.filledTonalIconToggleButtonColors(),
849 interactionSource: MutableInteractionSource? = null,
850 content: @Composable () -> Unit
851 ) =
852 SurfaceIconToggleButton(
853 checked = checked,
854 onCheckedChange = onCheckedChange,
855 modifier = modifier.semantics { role = Role.Checkbox },
856 enabled = enabled,
857 shape = shape,
858 colors = colors,
859 border = null,
860 interactionSource = interactionSource,
861 content = content
862 )
863
864 /**
865 * [Material Design filled tonal icon toggle
866 * button](https://m3.material.io/components/icon-button/overview)
867 *
868 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
869 * compact button is required, such as in a toolbar or image list.
870 *
871 * 
873 *
874 * A filled tonal toggle icon button is a medium-emphasis icon button that is an alternative middle
875 * ground between the default [FilledIconToggleButton] and [OutlinedIconToggleButton]. They can be
876 * used in contexts where the lower-priority icon button requires slightly more emphasis than an
877 * outline would give.
878 *
879 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
880 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
881 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
882 *
883 * Toggleable filled tonal icon button with animatable shape sample:
884 *
885 * @sample androidx.compose.material3.samples.FilledTonalIconToggleButtonWithAnimatedShapeSample
886 * @param checked whether this icon button is toggled on or off
887 * @param onCheckedChange called when this icon button is clicked
888 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
889 * user's interaction with the icon button.
890 * @param modifier the [Modifier] to be applied to this icon button
891 * @param enabled controls the enabled state of this icon button. When `false`, this component will
892 * not respond to user input, and it will appear visually disabled and disabled to accessibility
893 * services.
894 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
895 * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors].
896 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
897 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
898 * appearance or preview the icon button in different states. Note that if `null` is provided,
899 * interactions will still happen internally.
900 * @param content the content of this icon button, typically an [Icon]
901 */
902 @ExperimentalMaterial3ExpressiveApi
903 @Composable
FilledTonalIconToggleButtonnull904 fun FilledTonalIconToggleButton(
905 checked: Boolean,
906 onCheckedChange: (Boolean) -> Unit,
907 shapes: IconToggleButtonShapes,
908 modifier: Modifier = Modifier,
909 enabled: Boolean = true,
910 colors: IconToggleButtonColors = IconButtonDefaults.filledTonalIconToggleButtonColors(),
911 interactionSource: MutableInteractionSource? = null,
912 content: @Composable () -> Unit
913 ) =
914 SurfaceIconToggleButton(
915 checked = checked,
916 onCheckedChange = onCheckedChange,
917 modifier = modifier.semantics { role = Role.Checkbox },
918 enabled = enabled,
919 shapes = shapes,
920 colors = colors,
921 border = null,
922 interactionSource = interactionSource,
923 content = content
924 )
925
926 /**
927 * [Material Design outlined icon button](https://m3.material.io/components/icon-button/overview)
928 *
929 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
930 * compact button is required, such as in a toolbar or image list.
931 *
932 * 
934 *
935 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
936 * compact button is required, such as in a toolbar or image list.
937 *
938 * Use this "contained" icon button when the component requires more visual separation from the
939 * background.
940 *
941 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
942 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. The outlined icon
943 * button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
944 *
945 * @sample androidx.compose.material3.samples.OutlinedIconButtonSample
946 *
947 * Large-sized uniform rounded shape
948 *
949 * @sample androidx.compose.material3.samples.LargeRoundUniformOutlinedIconButtonSample
950 * @param onClick called when this icon button is clicked
951 * @param modifier the [Modifier] to be applied to this icon button
952 * @param enabled controls the enabled state of this icon button. When `false`, this component will
953 * not respond to user input, and it will appear visually disabled and disabled to accessibility
954 * services.
955 * @param shape defines the shape of this icon button's container and border (when [border] is not
956 * null)
957 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
958 * button in different states. See [IconButtonDefaults.outlinedIconButtonVibrantColors] and
959 * [IconButtonDefaults.outlinedIconButtonColors].
960 * @param border the border to draw around the container of this icon button. Pass `null` for no
961 * border. See [IconButtonDefaults.outlinedIconButtonBorder] and
962 * [IconButtonDefaults.outlinedIconButtonBorder].
963 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
964 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
965 * appearance or preview the icon button in different states. Note that if `null` is provided,
966 * interactions will still happen internally.
967 * @param content the content of this icon button, typically an [Icon]
968 */
969 @Composable
OutlinedIconButtonnull970 fun OutlinedIconButton(
971 onClick: () -> Unit,
972 modifier: Modifier = Modifier,
973 enabled: Boolean = true,
974 shape: Shape = IconButtonDefaults.outlinedShape,
975 colors: IconButtonColors = IconButtonDefaults.outlinedIconButtonColors(),
976 border: BorderStroke? = IconButtonDefaults.outlinedIconButtonBorder(enabled),
977 interactionSource: MutableInteractionSource? = null,
978 content: @Composable () -> Unit
979 ) =
980 SurfaceIconButton(
981 onClick = onClick,
982 modifier = modifier,
983 enabled = enabled,
984 shape = shape,
985 colors = colors,
986 border = border,
987 interactionSource = interactionSource,
988 content = content
989 )
990
991 /**
992 * [Material Design outlined icon button](https://m3.material.io/components/icon-button/overview)
993 *
994 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
995 * compact button is required, such as in a toolbar or image list.
996 *
997 * 
999 *
1000 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
1001 * compact button is required, such as in a toolbar or image list.
1002 *
1003 * Use this "contained" icon button when the component requires more visual separation from the
1004 * background.
1005 *
1006 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
1007 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. The outlined icon
1008 * button has an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
1009 *
1010 * Toggleable filled tonal icon button with animatable shape sample:
1011 *
1012 * @sample androidx.compose.material3.samples.OutlinedIconButtonWithAnimatedShapeSample
1013 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
1014 * user's interaction with the icon button.
1015 * @param onClick called when this icon button is clicked
1016 * @param modifier the [Modifier] to be applied to this icon button
1017 * @param enabled controls the enabled state of this icon button. When `false`, this component will
1018 * not respond to user input, and it will appear visually disabled and disabled to accessibility
1019 * services.
1020 * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon
1021 * button in different states. See [IconButtonDefaults.outlinedIconButtonVibrantColors] and
1022 * [IconButtonDefaults.outlinedIconButtonColors].
1023 * @param border the border to draw around the container of this icon button. Pass `null` for no
1024 * border. See [IconButtonDefaults.outlinedIconButtonBorder] and
1025 * [IconButtonDefaults.outlinedIconButtonBorder].
1026 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
1027 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
1028 * appearance or preview the icon button in different states. Note that if `null` is provided,
1029 * interactions will still happen internally.
1030 * @param content the content of this icon button, typically an [Icon]
1031 */
1032 @ExperimentalMaterial3ExpressiveApi
1033 @Composable
1034 fun OutlinedIconButton(
1035 onClick: () -> Unit,
1036 shapes: IconButtonShapes,
1037 modifier: Modifier = Modifier,
1038 enabled: Boolean = true,
1039 colors: IconButtonColors = IconButtonDefaults.outlinedIconButtonColors(),
1040 border: BorderStroke? = IconButtonDefaults.outlinedIconButtonBorder(enabled),
1041 interactionSource: MutableInteractionSource? = null,
1042 content: @Composable () -> Unit
1043 ) =
1044 SurfaceIconButton(
1045 onClick = onClick,
1046 modifier = modifier,
1047 enabled = enabled,
1048 shapes = shapes,
1049 colors = colors,
1050 border = border,
1051 interactionSource = interactionSource,
1052 content = content
1053 )
1054
1055 /**
1056 * [Material Design outlined icon toggle
1057 * button](https://m3.material.io/components/icon-button/overview)
1058 *
1059 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
1060 * compact button is required, such as in a toolbar or image list.
1061 *
1062 * 
1064 *
1065 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
1066 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
1067 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
1068 *
1069 * @sample androidx.compose.material3.samples.OutlinedIconToggleButtonSample
1070 * @param checked whether this icon button is toggled on or off
1071 * @param onCheckedChange called when this icon button is clicked
1072 * @param modifier the [Modifier] to be applied to this icon button
1073 * @param enabled controls the enabled state of this icon button. When `false`, this component will
1074 * not respond to user input, and it will appear visually disabled and disabled to accessibility
1075 * services.
1076 * @param shape defines the shape of this icon button's container and border (when [border] is not
1077 * null)
1078 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
1079 * button in different states. See [IconButtonDefaults.outlinedIconToggleButtonVibrantColors] and
1080 * [IconButtonDefaults.outlinedIconToggleButtonColors].
1081 * @param border the border to draw around the container of this icon button. Pass `null` for no
1082 * border. See [IconButtonDefaults.outlinedIconToggleButtonVibrantBorder] and
1083 * [IconButtonDefaults.outlinedIconToggleButtonBorder].
1084 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
1085 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
1086 * appearance or preview the icon button in different states. Note that if `null` is provided,
1087 * interactions will still happen internally.
1088 * @param content the content of this icon button, typically an [Icon]
1089 */
1090 @Composable
1091 fun OutlinedIconToggleButton(
1092 checked: Boolean,
1093 onCheckedChange: (Boolean) -> Unit,
1094 modifier: Modifier = Modifier,
1095 enabled: Boolean = true,
1096 shape: Shape = IconButtonDefaults.outlinedShape,
1097 colors: IconToggleButtonColors = IconButtonDefaults.outlinedIconToggleButtonColors(),
1098 border: BorderStroke? = IconButtonDefaults.outlinedIconToggleButtonBorder(enabled, checked),
1099 interactionSource: MutableInteractionSource? = null,
1100 content: @Composable () -> Unit
1101 ) =
1102 SurfaceIconToggleButton(
1103 checked = checked,
1104 onCheckedChange = onCheckedChange,
1105 modifier = modifier.semantics { role = Role.Checkbox },
1106 enabled = enabled,
1107 shape = shape,
1108 colors = colors,
1109 border = border,
1110 interactionSource = interactionSource,
1111 content = content
1112 )
1113
1114 /**
1115 * [Material Design outlined icon toggle
1116 * button](https://m3.material.io/components/icon-button/overview)
1117 *
1118 * Icon buttons help people take supplementary actions with a single tap. They’re used when a
1119 * compact button is required, such as in a toolbar or image list.
1120 *
1121 * 
1123 *
1124 * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a
1125 * custom icon, note that the typical size for the internal icon is 24 x 24 dp. This icon button has
1126 * an overall minimum touch target size of 48 x 48dp, to meet accessibility guidelines.
1127 *
1128 * @sample androidx.compose.material3.samples.OutlinedIconToggleButtonWithAnimatedShapeSample
1129 * @param checked whether this icon button is toggled on or off
1130 * @param onCheckedChange called when this icon button is clicked
1131 * @param shapes the [IconButtonShapes] that the icon button will morph between depending on the
1132 * user's interaction with the icon button.
1133 * @param modifier the [Modifier] to be applied to this icon button
1134 * @param enabled controls the enabled state of this icon button. When `false`, this component will
1135 * not respond to user input, and it will appear visually disabled and disabled to accessibility
1136 * services.
1137 * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon
1138 * button in different states. See [IconButtonDefaults.outlinedIconToggleButtonVibrantColors].
1139 * @param border the border to draw around the container of this icon button. Pass `null` for no
1140 * border. See [IconButtonDefaults.outlinedIconToggleButtonVibrantBorder].
1141 * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and
1142 * emitting [Interaction]s for this icon button. You can use this to change the icon button's
1143 * appearance or preview the icon button in different states. Note that if `null` is provided,
1144 * interactions will still happen internally.
1145 * @param content the content of this icon button, typically an [Icon]
1146 */
1147 @ExperimentalMaterial3ExpressiveApi
1148 @Composable
OutlinedIconToggleButtonnull1149 fun OutlinedIconToggleButton(
1150 checked: Boolean,
1151 onCheckedChange: (Boolean) -> Unit,
1152 shapes: IconToggleButtonShapes,
1153 modifier: Modifier = Modifier,
1154 enabled: Boolean = true,
1155 colors: IconToggleButtonColors = IconButtonDefaults.outlinedIconToggleButtonVibrantColors(),
1156 border: BorderStroke? =
1157 IconButtonDefaults.outlinedIconToggleButtonVibrantBorder(enabled, checked),
1158 interactionSource: MutableInteractionSource? = null,
1159 content: @Composable () -> Unit
1160 ) =
1161 SurfaceIconToggleButton(
1162 checked = checked,
1163 onCheckedChange = onCheckedChange,
1164 modifier = modifier.semantics { role = Role.Checkbox },
1165 enabled = enabled,
1166 shapes = shapes,
1167 colors = colors,
1168 border = border,
1169 interactionSource = interactionSource,
1170 content = content
1171 )
1172
1173 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
1174 @Composable
SurfaceIconButtonnull1175 private fun SurfaceIconButton(
1176 onClick: () -> Unit,
1177 modifier: Modifier,
1178 enabled: Boolean,
1179 shape: Shape,
1180 colors: IconButtonColors,
1181 border: BorderStroke?,
1182 interactionSource: MutableInteractionSource?,
1183 content: @Composable () -> Unit
1184 ) =
1185 Surface(
1186 onClick = onClick,
1187 modifier = modifier.semantics { role = Role.Button },
1188 enabled = enabled,
1189 shape = shape,
1190 color = colors.containerColor(enabled),
1191 contentColor = colors.contentColor(enabled),
1192 border = border,
1193 interactionSource = interactionSource
<lambda>null1194 ) {
1195 Box(
1196 modifier = Modifier.size(IconButtonDefaults.smallContainerSize()),
1197 contentAlignment = Alignment.Center
1198 ) {
1199 content()
1200 }
1201 }
1202
1203 @ExperimentalMaterial3ExpressiveApi
1204 @Composable
SurfaceIconButtonnull1205 private fun SurfaceIconButton(
1206 onClick: () -> Unit,
1207 modifier: Modifier,
1208 enabled: Boolean,
1209 shapes: IconButtonShapes,
1210 colors: IconButtonColors,
1211 border: BorderStroke?,
1212 interactionSource: MutableInteractionSource?,
1213 content: @Composable () -> Unit
1214 ) {
1215
1216 @Suppress("NAME_SHADOWING")
1217 val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
1218
1219 SurfaceIconButton(
1220 onClick = onClick,
1221 modifier = modifier,
1222 enabled = enabled,
1223 shape = shapeForInteraction(shapes, interactionSource),
1224 colors = colors,
1225 border = border,
1226 interactionSource = interactionSource,
1227 content = content
1228 )
1229 }
1230
1231 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
1232 @Composable
SurfaceIconToggleButtonnull1233 private fun SurfaceIconToggleButton(
1234 checked: Boolean,
1235 onCheckedChange: (Boolean) -> Unit,
1236 modifier: Modifier,
1237 enabled: Boolean,
1238 shape: Shape,
1239 colors: IconToggleButtonColors,
1240 border: BorderStroke?,
1241 interactionSource: MutableInteractionSource?,
1242 content: @Composable () -> Unit
1243 ) {
1244 Surface(
1245 checked = checked,
1246 onCheckedChange = onCheckedChange,
1247 modifier = modifier.semantics { role = Role.Checkbox },
1248 enabled = enabled,
1249 shape = shape,
1250 color = colors.containerColor(enabled, checked).value,
1251 contentColor = colors.contentColor(enabled, checked).value,
1252 border = border,
1253 interactionSource = interactionSource
1254 ) {
1255 Box(
1256 modifier =
1257 Modifier.size(
1258 IconButtonDefaults.smallContainerSize(),
1259 ),
1260 contentAlignment = Alignment.Center
1261 ) {
1262 content()
1263 }
1264 }
1265 }
1266
1267 @ExperimentalMaterial3ExpressiveApi
1268 @Composable
SurfaceIconToggleButtonnull1269 private fun SurfaceIconToggleButton(
1270 checked: Boolean,
1271 onCheckedChange: (Boolean) -> Unit,
1272 modifier: Modifier,
1273 enabled: Boolean,
1274 shapes: IconToggleButtonShapes,
1275 colors: IconToggleButtonColors,
1276 border: BorderStroke?,
1277 interactionSource: MutableInteractionSource?,
1278 content: @Composable () -> Unit
1279 ) {
1280
1281 @Suppress("NAME_SHADOWING")
1282 val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
1283
1284 SurfaceIconToggleButton(
1285 checked = checked,
1286 onCheckedChange = onCheckedChange,
1287 modifier = modifier,
1288 enabled = enabled,
1289 shape = shapeForInteraction(checked, shapes, interactionSource),
1290 colors = colors,
1291 border = border,
1292 interactionSource = interactionSource,
1293 content = content
1294 )
1295 }
1296
1297 /**
1298 * Represents the container and content colors used in an icon button in different states.
1299 *
1300 * @param containerColor the container color of this icon button when enabled.
1301 * @param contentColor the content color of this icon button when enabled.
1302 * @param disabledContainerColor the container color of this icon button when not enabled.
1303 * @param disabledContentColor the content color of this icon button when not enabled.
1304 * @constructor create an instance with arbitrary colors.
1305 * - See [IconButtonDefaults.filledIconButtonColors] and
1306 * [IconButtonDefaults.filledTonalIconButtonColors] for the default colors used in a
1307 * [FilledIconButton].
1308 * - See [IconButtonDefaults.outlinedIconButtonVibrantColors] for the default colors used in an
1309 * [OutlinedIconButton].
1310 */
1311 @Immutable
1312 class IconButtonColors(
1313 val containerColor: Color,
1314 val contentColor: Color,
1315 val disabledContainerColor: Color,
1316 val disabledContentColor: Color,
1317 ) {
1318
1319 /**
1320 * Returns a copy of this IconButtonColors, optionally overriding some of the values. This uses
1321 * the Color.Unspecified to mean “use the value from the source”
1322 */
copynull1323 fun copy(
1324 containerColor: Color = this.containerColor,
1325 contentColor: Color = this.contentColor,
1326 disabledContainerColor: Color = this.disabledContainerColor,
1327 disabledContentColor: Color = this.disabledContentColor,
1328 ) =
1329 IconButtonColors(
1330 containerColor.takeOrElse { this.containerColor },
<lambda>null1331 contentColor.takeOrElse { this.contentColor },
<lambda>null1332 disabledContainerColor.takeOrElse { this.disabledContainerColor },
<lambda>null1333 disabledContentColor.takeOrElse { this.disabledContentColor },
1334 )
1335
1336 /**
1337 * Represents the container color for this icon button, depending on [enabled].
1338 *
1339 * @param enabled whether the icon button is enabled
1340 */
1341 @Stable
containerColornull1342 internal fun containerColor(enabled: Boolean): Color =
1343 if (enabled) containerColor else disabledContainerColor
1344
1345 /**
1346 * Represents the content color for this icon button, depending on [enabled].
1347 *
1348 * @param enabled whether the icon button is enabled
1349 */
1350 @Stable
1351 internal fun contentColor(enabled: Boolean): Color =
1352 if (enabled) contentColor else disabledContentColor
1353
1354 override fun equals(other: Any?): Boolean {
1355 if (this === other) return true
1356 if (other == null || other !is IconButtonColors) return false
1357
1358 if (containerColor != other.containerColor) return false
1359 if (contentColor != other.contentColor) return false
1360 if (disabledContainerColor != other.disabledContainerColor) return false
1361 if (disabledContentColor != other.disabledContentColor) return false
1362
1363 return true
1364 }
1365
hashCodenull1366 override fun hashCode(): Int {
1367 var result = containerColor.hashCode()
1368 result = 31 * result + contentColor.hashCode()
1369 result = 31 * result + disabledContainerColor.hashCode()
1370 result = 31 * result + disabledContentColor.hashCode()
1371
1372 return result
1373 }
1374 }
1375
1376 /**
1377 * Represents the container and content colors used in a toggleable icon button in different states.
1378 *
1379 * @param containerColor the container color of this icon button when enabled.
1380 * @param contentColor the content color of this icon button when enabled.
1381 * @param disabledContainerColor the container color of this icon button when not enabled.
1382 * @param disabledContentColor the content color of this icon button when not enabled.
1383 * @param checkedContainerColor the container color of this icon button when checked.
1384 * @param checkedContentColor the content color of this icon button when checked.
1385 * @constructor create an instance with arbitrary colors.
1386 * - See [IconButtonDefaults.filledIconToggleButtonColors] and
1387 * [IconButtonDefaults.filledTonalIconToggleButtonColors] for the default colors used in a
1388 * [FilledIconButton].
1389 * - See [IconButtonDefaults.outlinedIconToggleButtonVibrantColors] for the default colors used in a
1390 * toggleable [OutlinedIconButton].
1391 */
1392 @Immutable
1393 class IconToggleButtonColors(
1394 val containerColor: Color,
1395 val contentColor: Color,
1396 val disabledContainerColor: Color,
1397 val disabledContentColor: Color,
1398 val checkedContainerColor: Color,
1399 val checkedContentColor: Color,
1400 ) {
1401
1402 /**
1403 * Returns a copy of this IconToggleButtonColors, optionally overriding some of the values. This
1404 * uses the Color.Unspecified to mean “use the value from the source”
1405 */
copynull1406 fun copy(
1407 containerColor: Color = this.containerColor,
1408 contentColor: Color = this.contentColor,
1409 disabledContainerColor: Color = this.disabledContainerColor,
1410 disabledContentColor: Color = this.disabledContentColor,
1411 checkedContainerColor: Color = this.checkedContainerColor,
1412 checkedContentColor: Color = this.checkedContentColor
1413 ) =
1414 IconToggleButtonColors(
1415 containerColor.takeOrElse { this.containerColor },
<lambda>null1416 contentColor.takeOrElse { this.contentColor },
<lambda>null1417 disabledContainerColor.takeOrElse { this.disabledContainerColor },
<lambda>null1418 disabledContentColor.takeOrElse { this.disabledContentColor },
<lambda>null1419 checkedContainerColor.takeOrElse { this.checkedContainerColor },
<lambda>null1420 checkedContentColor.takeOrElse { this.checkedContentColor }
1421 )
1422
1423 /**
1424 * Represents the container color for this icon button, depending on [enabled] and [checked].
1425 *
1426 * @param enabled whether the icon button is enabled
1427 * @param checked whether the icon button is checked
1428 */
1429 @Composable
containerColornull1430 internal fun containerColor(enabled: Boolean, checked: Boolean): State<Color> {
1431 val target =
1432 when {
1433 !enabled -> disabledContainerColor
1434 !checked -> containerColor
1435 else -> checkedContainerColor
1436 }
1437 return rememberUpdatedState(target)
1438 }
1439
1440 /**
1441 * Represents the content color for this icon button, depending on [enabled] and [checked].
1442 *
1443 * @param enabled whether the icon button is enabled
1444 * @param checked whether the icon button is checked
1445 */
1446 @Composable
contentColornull1447 internal fun contentColor(enabled: Boolean, checked: Boolean): State<Color> {
1448 val target =
1449 when {
1450 !enabled -> disabledContentColor
1451 !checked -> contentColor
1452 else -> checkedContentColor
1453 }
1454 return rememberUpdatedState(target)
1455 }
1456
equalsnull1457 override fun equals(other: Any?): Boolean {
1458 if (this === other) return true
1459 if (other == null || other !is IconToggleButtonColors) return false
1460
1461 if (containerColor != other.containerColor) return false
1462 if (contentColor != other.contentColor) return false
1463 if (disabledContainerColor != other.disabledContainerColor) return false
1464 if (disabledContentColor != other.disabledContentColor) return false
1465 if (checkedContainerColor != other.checkedContainerColor) return false
1466 if (checkedContentColor != other.checkedContentColor) return false
1467
1468 return true
1469 }
1470
hashCodenull1471 override fun hashCode(): Int {
1472 var result = containerColor.hashCode()
1473 result = 31 * result + contentColor.hashCode()
1474 result = 31 * result + disabledContainerColor.hashCode()
1475 result = 31 * result + disabledContentColor.hashCode()
1476 result = 31 * result + checkedContainerColor.hashCode()
1477 result = 31 * result + checkedContentColor.hashCode()
1478
1479 return result
1480 }
1481 }
1482
1483 /**
1484 * The shapes that will be used in icon buttons. Icon button will morph between these shapes
1485 * depending on the interaction of the icon button, assuming all of the shapes are
1486 * [CornerBasedShape]s.
1487 *
1488 * @property shape is the unchecked shape.
1489 * @property pressedShape is the pressed shape.
1490 */
1491 @ExperimentalMaterial3ExpressiveApi
1492 class IconButtonShapes(val shape: Shape, val pressedShape: Shape = shape) {
1493
1494 /** Returns a copy of this IconButtonShapes, optionally overriding some of the values. */
copynull1495 fun copy(
1496 shape: Shape? = this.shape,
1497 pressedShape: Shape? = this.pressedShape,
1498 ) =
1499 IconButtonShapes(
1500 shape = shape.takeOrElse { this.shape },
<lambda>null1501 pressedShape = pressedShape.takeOrElse { this.pressedShape },
1502 )
1503
takeOrElsenull1504 internal fun Shape?.takeOrElse(block: () -> Shape): Shape = this ?: block()
1505
1506 override fun equals(other: Any?): Boolean {
1507 if (this === other) return true
1508 if (other == null || other !is IconButtonShapes) return false
1509
1510 if (shape != other.shape) return false
1511 if (pressedShape != other.pressedShape) return false
1512
1513 return true
1514 }
1515
hashCodenull1516 override fun hashCode(): Int {
1517 var result = shape.hashCode()
1518 result = 31 * result + pressedShape.hashCode()
1519
1520 return result
1521 }
1522 }
1523
1524 /**
1525 * The shapes that will be used in toggle buttons. Toggle button will morph between these three
1526 * shapes depending on the interaction of the toggle button, assuming all of the shapes are
1527 * [CornerBasedShape]s.
1528 *
1529 * @property shape is the unchecked shape.
1530 * @property pressedShape is the pressed shape.
1531 * @property checkedShape is the checked shape.
1532 */
1533 @ExperimentalMaterial3ExpressiveApi
1534 class IconToggleButtonShapes(
1535 val shape: Shape,
1536 val pressedShape: Shape = shape,
1537 val checkedShape: Shape = shape
1538 ) {
1539
1540 /** Returns a copy of this IconButtonShapes, optionally overriding some of the values. */
copynull1541 fun copy(
1542 shape: Shape? = this.shape,
1543 pressedShape: Shape? = this.pressedShape,
1544 checkedShape: Shape? = this.checkedShape
1545 ) =
1546 IconToggleButtonShapes(
1547 shape = shape.takeOrElse { this.shape },
<lambda>null1548 pressedShape = pressedShape.takeOrElse { this.pressedShape },
<lambda>null1549 checkedShape = checkedShape.takeOrElse { this.checkedShape }
1550 )
1551
takeOrElsenull1552 internal fun Shape?.takeOrElse(block: () -> Shape): Shape = this ?: block()
1553
1554 override fun equals(other: Any?): Boolean {
1555 if (this === other) return true
1556 if (other == null || other !is IconToggleButtonShapes) return false
1557
1558 if (shape != other.shape) return false
1559 if (pressedShape != other.pressedShape) return false
1560 if (checkedShape != other.checkedShape) return false
1561
1562 return true
1563 }
1564
hashCodenull1565 override fun hashCode(): Int {
1566 var result = shape.hashCode()
1567 result = 31 * result + pressedShape.hashCode()
1568 result = 31 * result + checkedShape.hashCode()
1569
1570 return result
1571 }
1572 }
1573
1574 @ExperimentalMaterial3ExpressiveApi
1575 @Composable
shapeForInteractionnull1576 private fun shapeForInteraction(
1577 shapes: IconButtonShapes,
1578 interactionSource: MutableInteractionSource,
1579 ): Shape {
1580 if (shapes.isStatic) {
1581 return shapes.shape
1582 }
1583 // TODO Load the motionScheme tokens from the component tokens file
1584 // MotionSchemeKeyTokens.DefaultEffects is intentional here to prevent
1585 // any bounce in this component.
1586 val defaultAnimationSpec = MotionSchemeKeyTokens.DefaultEffects.value<Float>()
1587 val pressed by interactionSource.collectIsPressedAsState()
1588
1589 return shapeByInteraction(shapes, pressed, defaultAnimationSpec)
1590 }
1591
1592 @ExperimentalMaterial3ExpressiveApi
1593 @Composable
shapeForInteractionnull1594 private fun shapeForInteraction(
1595 checked: Boolean,
1596 shapes: IconToggleButtonShapes,
1597 interactionSource: MutableInteractionSource,
1598 ): Shape {
1599 if (shapes.isStatic) {
1600 return shapes.shape
1601 }
1602 // TODO Load the motionScheme tokens from the component tokens file
1603 // MotionSchemeKeyTokens.DefaultEffects is intentional here to prevent
1604 // any bounce in this component.
1605 val defaultAnimationSpec = MotionSchemeKeyTokens.DefaultEffects.value<Float>()
1606 val pressed by interactionSource.collectIsPressedAsState()
1607
1608 return shapeByInteraction(shapes, pressed, checked, defaultAnimationSpec)
1609 }
1610
1611 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
1612 internal val IconButtonShapes.isCornerBasedShape: Boolean
1613 get() = shape is RoundedCornerShape && pressedShape is CornerBasedShape
1614
1615 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
1616 internal val IconButtonShapes.isStatic: Boolean
1617 get() = shape === pressedShape
1618
1619 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
1620 internal val IconToggleButtonShapes.isCornerBasedShape: Boolean
1621 get() =
1622 shape is RoundedCornerShape &&
1623 pressedShape is CornerBasedShape &&
1624 checkedShape is CornerBasedShape
1625
1626 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
1627 internal val IconToggleButtonShapes.isStatic: Boolean
1628 get() = shape === pressedShape && shape === checkedShape
1629
1630 @ExperimentalMaterial3ExpressiveApi
1631 @Composable
shapeByInteractionnull1632 private fun shapeByInteraction(
1633 shapes: IconButtonShapes,
1634 pressed: Boolean,
1635 animationSpec: FiniteAnimationSpec<Float>
1636 ): Shape {
1637 val shape =
1638 if (pressed) {
1639 shapes.pressedShape
1640 } else shapes.shape
1641
1642 if (shapes.isCornerBasedShape) {
1643 return key(shapes) { rememberAnimatedShape(shape as RoundedCornerShape, animationSpec) }
1644 }
1645 return shape
1646 }
1647
1648 @ExperimentalMaterial3ExpressiveApi
1649 @Composable
shapeByInteractionnull1650 private fun shapeByInteraction(
1651 shapes: IconToggleButtonShapes,
1652 pressed: Boolean,
1653 checked: Boolean,
1654 animationSpec: FiniteAnimationSpec<Float>
1655 ): Shape {
1656 val shape =
1657 if (pressed) {
1658 shapes.pressedShape
1659 } else if (checked) {
1660 shapes.checkedShape
1661 } else shapes.shape
1662
1663 if (shapes.isCornerBasedShape) {
1664 return key(shapes) { rememberAnimatedShape(shape as RoundedCornerShape, animationSpec) }
1665 }
1666 return shape
1667 }
1668