| /* |
| * Copyright 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package androidx.compose.material3 |
| |
| import androidx.compose.foundation.BorderStroke |
| import androidx.compose.foundation.background |
| import androidx.compose.foundation.clickable |
| import androidx.compose.foundation.interaction.Interaction |
| import androidx.compose.foundation.interaction.MutableInteractionSource |
| import androidx.compose.foundation.layout.Box |
| import androidx.compose.foundation.layout.size |
| import androidx.compose.foundation.selection.toggleable |
| import androidx.compose.material.ripple.rememberRipple |
| import androidx.compose.material3.tokens.FilledIconButtonTokens |
| import androidx.compose.material3.tokens.FilledTonalIconButtonTokens |
| import androidx.compose.material3.tokens.IconButtonTokens |
| import androidx.compose.material3.tokens.OutlinedIconButtonTokens |
| import androidx.compose.runtime.Composable |
| import androidx.compose.runtime.CompositionLocalProvider |
| import androidx.compose.runtime.Immutable |
| import androidx.compose.runtime.Stable |
| import androidx.compose.runtime.State |
| import androidx.compose.runtime.remember |
| import androidx.compose.runtime.rememberUpdatedState |
| import androidx.compose.ui.Alignment |
| import androidx.compose.ui.Modifier |
| import androidx.compose.ui.graphics.Color |
| import androidx.compose.ui.graphics.Shape |
| import androidx.compose.ui.semantics.Role |
| import androidx.compose.ui.semantics.role |
| import androidx.compose.ui.semantics.semantics |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design standard icon button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Standard icon button image](https://developer.android.com/images/reference/androidx/compose/material3/standard-icon-button.png) |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * @sample androidx.compose.material3.samples.IconButtonSample |
| * |
| * @param onClick called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.iconButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @Composable |
| fun IconButton( |
| onClick: () -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| colors: IconButtonColors = IconButtonDefaults.iconButtonColors(), |
| content: @Composable () -> Unit |
| ) { |
| Box( |
| modifier = |
| modifier |
| .minimumTouchTargetSize() |
| .size(IconButtonTokens.StateLayerSize) |
| .background(color = colors.containerColor(enabled).value) |
| .clickable( |
| onClick = onClick, |
| enabled = enabled, |
| role = Role.Button, |
| interactionSource = interactionSource, |
| indication = rememberRipple( |
| bounded = false, |
| radius = IconButtonTokens.StateLayerSize / 2 |
| ) |
| ), |
| contentAlignment = Alignment.Center |
| ) { |
| val contentColor = colors.contentColor(enabled).value |
| CompositionLocalProvider(LocalContentColor provides contentColor, content = content) |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design standard icon toggle button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Standard icon toggle button image](https://developer.android.com/images/reference/androidx/compose/material3/standard-icon-toggle-button.png) |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * @sample androidx.compose.material3.samples.IconToggleButtonSample |
| * |
| * @param checked whether this icon button is toggled on or off |
| * @param onCheckedChange called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.iconToggleButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @Composable |
| fun IconToggleButton( |
| checked: Boolean, |
| onCheckedChange: (Boolean) -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| colors: IconToggleButtonColors = IconButtonDefaults.iconToggleButtonColors(), |
| content: @Composable () -> Unit |
| ) { |
| Box( |
| modifier = |
| modifier |
| .minimumTouchTargetSize() |
| .size(IconButtonTokens.StateLayerSize) |
| .background(color = colors.containerColor(enabled, checked).value) |
| .toggleable( |
| value = checked, |
| onValueChange = onCheckedChange, |
| enabled = enabled, |
| role = Role.Checkbox, |
| interactionSource = interactionSource, |
| indication = rememberRipple( |
| bounded = false, |
| radius = IconButtonTokens.StateLayerSize / 2 |
| ) |
| ), |
| contentAlignment = Alignment.Center |
| ) { |
| val contentColor = colors.contentColor(enabled, checked).value |
| CompositionLocalProvider(LocalContentColor provides contentColor, content = content) |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design filled icon button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Filled icon button image](https://developer.android.com/images/reference/androidx/compose/material3/filled-icon-button.png) |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * Filled icon button sample: |
| * @sample androidx.compose.material3.samples.FilledIconButtonSample |
| * |
| * @param onClick called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param shape defines the shape of this icon button's container |
| * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.filledIconButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @ExperimentalMaterial3Api |
| @Composable |
| fun FilledIconButton( |
| onClick: () -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| shape: Shape = IconButtonDefaults.filledShape, |
| colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors(), |
| content: @Composable () -> Unit |
| ) = Surface( |
| onClick = onClick, |
| modifier = modifier, |
| enabled = enabled, |
| shape = shape, |
| color = colors.containerColor(enabled).value, |
| contentColor = colors.contentColor(enabled).value, |
| interactionSource = interactionSource |
| ) { |
| Box( |
| modifier = Modifier.size(FilledIconButtonTokens.ContainerSize), |
| contentAlignment = Alignment.Center |
| ) { |
| content() |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design filled tonal icon button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Filled tonal icon button image](https://developer.android.com/images/reference/androidx/compose/material3/filled-tonal-icon-button.png) |
| * |
| * A filled tonal icon button is a medium-emphasis icon button that is an alternative middle |
| * ground between the default [FilledIconButton] and [OutlinedIconButton]. |
| * They can be used in contexts where the lower-priority icon button requires slightly more emphasis |
| * than an outline would give. |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * Filled tonal icon button sample: |
| * @sample androidx.compose.material3.samples.FilledTonalIconButtonSample |
| * |
| * @param onClick called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param shape defines the shape of this icon button's container |
| * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.filledIconButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @ExperimentalMaterial3Api |
| @Composable |
| fun FilledTonalIconButton( |
| onClick: () -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| shape: Shape = IconButtonDefaults.filledShape, |
| colors: IconButtonColors = IconButtonDefaults.filledTonalIconButtonColors(), |
| content: @Composable () -> Unit |
| ) = Surface( |
| onClick = onClick, |
| modifier = modifier, |
| enabled = enabled, |
| shape = shape, |
| color = colors.containerColor(enabled).value, |
| contentColor = colors.contentColor(enabled).value, |
| interactionSource = interactionSource |
| ) { |
| Box( |
| modifier = Modifier.size(FilledTonalIconButtonTokens.ContainerSize), |
| contentAlignment = Alignment.Center |
| ) { |
| content() |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design filled icon toggle button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Filled icon toggle button image](https://developer.android.com/images/reference/androidx/compose/material3/filled-icon-toggle-button.png) |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * Toggleable filled icon button sample: |
| * @sample androidx.compose.material3.samples.FilledIconToggleButtonSample |
| * |
| * @param checked whether this icon button is toggled on or off |
| * @param onCheckedChange called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param shape defines the shape of this icon button's container |
| * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @ExperimentalMaterial3Api |
| @Composable |
| fun FilledIconToggleButton( |
| checked: Boolean, |
| onCheckedChange: (Boolean) -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| shape: Shape = IconButtonDefaults.filledShape, |
| colors: IconToggleButtonColors = IconButtonDefaults.filledIconToggleButtonColors(), |
| content: @Composable () -> Unit |
| ) = Surface( |
| checked = checked, |
| onCheckedChange = onCheckedChange, |
| modifier = modifier.semantics { role = Role.Checkbox }, |
| enabled = enabled, |
| shape = shape, |
| color = colors.containerColor(enabled, checked).value, |
| contentColor = colors.contentColor(enabled, checked).value, |
| interactionSource = interactionSource |
| ) { |
| Box( |
| modifier = Modifier.size(FilledIconButtonTokens.ContainerSize), |
| contentAlignment = Alignment.Center |
| ) { |
| content() |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design filled tonal icon toggle button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Filled tonal icon toggle button image](https://developer.android.com/images/reference/androidx/compose/material3/filled-tonal-icon-toggle-button.png) |
| * |
| * A filled tonal toggle icon button is a medium-emphasis icon button that is an alternative |
| * middle ground between the default [FilledIconToggleButton] and [OutlinedIconToggleButton]. |
| * They can be used in contexts where the lower-priority icon button requires slightly more emphasis |
| * than an outline would give. |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * Toggleable filled tonal icon button sample: |
| * @sample androidx.compose.material3.samples.FilledTonalIconToggleButtonSample |
| * |
| * @param checked whether this icon button is toggled on or off |
| * @param onCheckedChange called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param shape defines the shape of this icon button's container |
| * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.filledIconToggleButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @ExperimentalMaterial3Api |
| @Composable |
| fun FilledTonalIconToggleButton( |
| checked: Boolean, |
| onCheckedChange: (Boolean) -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| shape: Shape = IconButtonDefaults.filledShape, |
| colors: IconToggleButtonColors = IconButtonDefaults.filledTonalIconToggleButtonColors(), |
| content: @Composable () -> Unit |
| ) = Surface( |
| checked = checked, |
| onCheckedChange = onCheckedChange, |
| modifier = modifier.semantics { role = Role.Checkbox }, |
| enabled = enabled, |
| shape = shape, |
| color = colors.containerColor(enabled, checked).value, |
| contentColor = colors.contentColor(enabled, checked).value, |
| interactionSource = interactionSource |
| ) { |
| Box( |
| modifier = Modifier.size(FilledTonalIconButtonTokens.ContainerSize), |
| contentAlignment = Alignment.Center |
| ) { |
| content() |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design outlined icon button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Outlined icon button image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-icon-button.png) |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * Use this "contained" icon button when the component requires more visual separation from the |
| * background. |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * The outlined icon button has an overall minimum touch target size of 48 x 48dp, to meet |
| * accessibility guidelines. |
| * |
| * @sample androidx.compose.material3.samples.OutlinedIconButtonSample |
| * |
| * @param onClick called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param shape defines the shape of this icon button's container and border (when [border] is not |
| * null) |
| * @param border the border to draw around the container of this icon button. Pass `null` for no |
| * border. See [IconButtonDefaults.outlinedIconButtonBorder]. |
| * @param colors [IconButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.outlinedIconButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @ExperimentalMaterial3Api |
| @Composable |
| fun OutlinedIconButton( |
| onClick: () -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| shape: Shape = IconButtonDefaults.outlinedShape, |
| border: BorderStroke? = IconButtonDefaults.outlinedIconButtonBorder(enabled), |
| colors: IconButtonColors = IconButtonDefaults.outlinedIconButtonColors(), |
| content: @Composable () -> Unit |
| ) = Surface( |
| onClick = onClick, |
| modifier = modifier, |
| enabled = enabled, |
| shape = shape, |
| color = colors.containerColor(enabled).value, |
| contentColor = colors.contentColor(enabled).value, |
| border = border, |
| interactionSource = interactionSource |
| ) { |
| Box( |
| modifier = Modifier.size(OutlinedIconButtonTokens.ContainerSize), |
| contentAlignment = Alignment.Center |
| ) { |
| content() |
| } |
| } |
| |
| /** |
| * <a href="https://m3.material.io/components/icon-button/overview" class="external" target="_blank">Material Design outlined icon toggle button</a>. |
| * |
| * Icon buttons help people take supplementary actions with a single tap. They’re used when a |
| * compact button is required, such as in a toolbar or image list. |
| * |
| * ![Outlined icon toggle button image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-icon-toggle-button.png) |
| * |
| * [content] should typically be an [Icon] (see [androidx.compose.material.icons.Icons]). If using a |
| * custom icon, note that the typical size for the internal icon is 24 x 24 dp. |
| * This icon button has an overall minimum touch target size of 48 x 48dp, to meet accessibility |
| * guidelines. |
| * |
| * @sample androidx.compose.material3.samples.OutlinedIconToggleButtonSample |
| * |
| * @param checked whether this icon button is toggled on or off |
| * @param onCheckedChange called when this icon button is clicked |
| * @param modifier the [Modifier] to be applied to this icon button |
| * @param enabled controls the enabled state of this icon button. When `false`, this component will |
| * not respond to user input, and it will appear visually disabled and disabled to accessibility |
| * services. |
| * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s |
| * for this icon button. You can create and pass in your own `remember`ed instance to observe |
| * [Interaction]s and customize the appearance / behavior of this icon button in different states. |
| * @param shape defines the shape of this icon button's container and border (when [border] is not |
| * null) |
| * @param border the border to draw around the container of this icon button. Pass `null` for no |
| * border. See [IconButtonDefaults.outlinedIconToggleButtonBorder]. |
| * @param colors [IconToggleButtonColors] that will be used to resolve the colors used for this icon |
| * button in different states. See [IconButtonDefaults.outlinedIconToggleButtonColors]. |
| * @param content the content of this icon button, typically an [Icon] |
| */ |
| @ExperimentalMaterial3Api |
| @Composable |
| fun OutlinedIconToggleButton( |
| checked: Boolean, |
| onCheckedChange: (Boolean) -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, |
| shape: Shape = IconButtonDefaults.outlinedShape, |
| border: BorderStroke? = IconButtonDefaults.outlinedIconToggleButtonBorder(enabled, checked), |
| colors: IconToggleButtonColors = IconButtonDefaults.outlinedIconToggleButtonColors(), |
| content: @Composable () -> Unit |
| ) = Surface( |
| checked = checked, |
| onCheckedChange = onCheckedChange, |
| modifier = modifier.semantics { role = Role.Checkbox }, |
| enabled = enabled, |
| shape = shape, |
| color = colors.containerColor(enabled, checked).value, |
| contentColor = colors.contentColor(enabled, checked).value, |
| border = border, |
| interactionSource = interactionSource |
| ) { |
| Box( |
| modifier = Modifier.size(OutlinedIconButtonTokens.ContainerSize), |
| contentAlignment = Alignment.Center |
| ) { |
| content() |
| } |
| } |
| |
| /** |
| * Represents the container and content colors used in an icon button in different states. |
| * |
| * - See [IconButtonDefaults.filledIconButtonColors] and |
| * [IconButtonDefaults.filledTonalIconButtonColors] for the default colors used in a |
| * [FilledIconButton]. |
| * - See [IconButtonDefaults.outlinedIconButtonColors] for the default colors used in an |
| * [OutlinedIconButton]. |
| */ |
| @Stable |
| interface IconButtonColors { |
| /** |
| * Represents the container color for this icon button, depending on [enabled]. |
| * |
| * @param enabled whether the icon button is enabled |
| */ |
| @Composable |
| fun containerColor(enabled: Boolean): State<Color> |
| |
| /** |
| * Represents the content color for this icon button, depending on [enabled]. |
| * |
| * @param enabled whether the icon button is enabled |
| */ |
| @Composable |
| fun contentColor(enabled: Boolean): State<Color> |
| } |
| |
| /** |
| * Represents the container and content colors used in a toggleable icon button in |
| * different states. |
| * |
| * - See [IconButtonDefaults.filledIconToggleButtonColors] and |
| * [IconButtonDefaults.filledTonalIconToggleButtonColors] for the default colors used in a |
| * [FilledIconButton]. |
| * - See [IconButtonDefaults.outlinedIconToggleButtonColors] for the default colors used in a |
| * toggleable [OutlinedIconButton]. |
| */ |
| @Stable |
| interface IconToggleButtonColors { |
| /** |
| * Represents the container color for this icon button, depending on [enabled] and [checked]. |
| * |
| * @param enabled whether the icon button is enabled |
| * @param checked whether the icon button is checked |
| */ |
| @Composable |
| fun containerColor(enabled: Boolean, checked: Boolean): State<Color> |
| |
| /** |
| * Represents the content color for this icon button, depending on [enabled] and [checked]. |
| * |
| * @param enabled whether the icon button is enabled |
| * @param checked whether the icon button is checked |
| */ |
| @Composable |
| fun contentColor(enabled: Boolean, checked: Boolean): State<Color> |
| } |
| |
| /** |
| * Contains the default values used by all icon button types. |
| */ |
| object IconButtonDefaults { |
| /** Default shape for a filled icon button. */ |
| val filledShape: Shape @Composable get() = FilledIconButtonTokens.ContainerShape.toShape() |
| |
| /** Default shape for an outlined icon button. */ |
| val outlinedShape: Shape @Composable get() = |
| OutlinedIconButtonTokens.ContainerShape.toShape() |
| |
| /** |
| * Creates a [IconButtonColors] that represents the default colors used in a [IconButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| */ |
| @Composable |
| fun iconButtonColors( |
| containerColor: Color = Color.Transparent, |
| contentColor: Color = LocalContentColor.current, |
| disabledContainerColor: Color = Color.Transparent, |
| disabledContentColor: Color = |
| contentColor.copy(alpha = IconButtonTokens.DisabledIconOpacity) |
| ): IconButtonColors = |
| DefaultIconButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| ) |
| |
| /** |
| * Creates a [IconToggleButtonColors] that represents the default colors used in a |
| * [IconToggleButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| * @param checkedContainerColor the container color of this icon button when checked. |
| * @param checkedContentColor the content color of this icon button when checked. |
| */ |
| @Composable |
| fun iconToggleButtonColors( |
| containerColor: Color = Color.Transparent, |
| contentColor: Color = LocalContentColor.current, |
| disabledContainerColor: Color = Color.Transparent, |
| disabledContentColor: Color = |
| contentColor.copy(alpha = IconButtonTokens.DisabledIconOpacity), |
| checkedContainerColor: Color = Color.Transparent, |
| checkedContentColor: Color = IconButtonTokens.SelectedIconColor.toColor() |
| ): IconToggleButtonColors = |
| DefaultIconToggleButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| ) |
| |
| /** |
| * Creates a [IconButtonColors] that represents the default colors used in a [FilledIconButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| */ |
| @Composable |
| fun filledIconButtonColors( |
| containerColor: Color = FilledIconButtonTokens.ContainerColor.toColor(), |
| contentColor: Color = contentColorFor(containerColor), |
| disabledContainerColor: Color = FilledIconButtonTokens.DisabledContainerColor.toColor() |
| .copy(alpha = FilledIconButtonTokens.DisabledContainerOpacity), |
| disabledContentColor: Color = FilledIconButtonTokens.DisabledColor.toColor() |
| .copy(alpha = FilledIconButtonTokens.DisabledOpacity) |
| ): IconButtonColors = |
| DefaultIconButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| ) |
| |
| /** |
| * Creates a [IconToggleButtonColors] that represents the default colors used in a |
| * [FilledIconToggleButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| * @param checkedContainerColor the container color of this icon button when checked. |
| * @param checkedContentColor the content color of this icon button when checked. |
| */ |
| @Composable |
| fun filledIconToggleButtonColors( |
| containerColor: Color = FilledIconButtonTokens.UnselectedContainerColor.toColor(), |
| // TODO(b/228455081): Using contentColorFor here will return OnSurfaceVariant, |
| // while the token value is Primary. |
| contentColor: Color = FilledIconButtonTokens.ToggleUnselectedColor.toColor(), |
| disabledContainerColor: Color = FilledIconButtonTokens.DisabledContainerColor.toColor() |
| .copy(alpha = FilledIconButtonTokens.DisabledContainerOpacity), |
| disabledContentColor: Color = FilledIconButtonTokens.DisabledColor.toColor() |
| .copy(alpha = FilledIconButtonTokens.DisabledOpacity), |
| checkedContainerColor: Color = FilledIconButtonTokens.SelectedContainerColor.toColor(), |
| checkedContentColor: Color = contentColorFor(checkedContainerColor) |
| ): IconToggleButtonColors = |
| DefaultIconToggleButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| ) |
| |
| /** |
| * Creates a [IconButtonColors] that represents the default colors used in a |
| * [FilledTonalIconButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| */ |
| @Composable |
| fun filledTonalIconButtonColors( |
| containerColor: Color = FilledTonalIconButtonTokens.ContainerColor.toColor(), |
| contentColor: Color = contentColorFor(containerColor), |
| disabledContainerColor: Color = FilledTonalIconButtonTokens.DisabledContainerColor.toColor() |
| .copy(alpha = FilledTonalIconButtonTokens.DisabledContainerOpacity), |
| disabledContentColor: Color = FilledTonalIconButtonTokens.DisabledColor.toColor() |
| .copy(alpha = FilledTonalIconButtonTokens.DisabledOpacity) |
| ): IconButtonColors = |
| DefaultIconButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| ) |
| |
| /** |
| * Creates a [IconToggleButtonColors] that represents the default colors used in a |
| * [FilledTonalIconToggleButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| * @param checkedContainerColor the container color of this icon button when checked. |
| * @param checkedContentColor the content color of this icon button when checked. |
| */ |
| @Composable |
| fun filledTonalIconToggleButtonColors( |
| containerColor: Color = FilledTonalIconButtonTokens.UnselectedContainerColor.toColor(), |
| contentColor: Color = contentColorFor(containerColor), |
| disabledContainerColor: Color = FilledTonalIconButtonTokens.DisabledContainerColor.toColor() |
| .copy(alpha = FilledTonalIconButtonTokens.DisabledContainerOpacity), |
| disabledContentColor: Color = FilledTonalIconButtonTokens.DisabledColor.toColor() |
| .copy(alpha = FilledTonalIconButtonTokens.DisabledOpacity), |
| checkedContainerColor: Color = |
| FilledTonalIconButtonTokens.SelectedContainerColor.toColor(), |
| checkedContentColor: Color = FilledTonalIconButtonTokens.ToggleSelectedColor.toColor() |
| ): IconToggleButtonColors = |
| DefaultIconToggleButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| ) |
| |
| /** |
| * Creates a [IconButtonColors] that represents the default colors used in a |
| * [OutlinedIconButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| */ |
| @Composable |
| fun outlinedIconButtonColors( |
| containerColor: Color = Color.Transparent, |
| contentColor: Color = LocalContentColor.current, |
| disabledContainerColor: Color = Color.Transparent, |
| disabledContentColor: Color = |
| contentColor.copy(alpha = OutlinedIconButtonTokens.DisabledOpacity) |
| ): IconButtonColors = |
| DefaultIconButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| ) |
| |
| /** |
| * Creates a [IconToggleButtonColors] that represents the default colors used in a |
| * [OutlinedIconToggleButton]. |
| * |
| * @param containerColor the container color of this icon button when enabled. |
| * @param contentColor the content color of this icon button when enabled. |
| * @param disabledContainerColor the container color of this icon button when not enabled. |
| * @param disabledContentColor the content color of this icon button when not enabled. |
| * @param checkedContainerColor the container color of this icon button when checked. |
| * @param checkedContentColor the content color of this icon button when checked. |
| */ |
| @Composable |
| fun outlinedIconToggleButtonColors( |
| containerColor: Color = Color.Transparent, |
| contentColor: Color = LocalContentColor.current, |
| disabledContainerColor: Color = Color.Transparent, |
| disabledContentColor: Color = |
| contentColor.copy(alpha = OutlinedIconButtonTokens.DisabledOpacity), |
| checkedContainerColor: Color = |
| OutlinedIconButtonTokens.SelectedContainerColor.toColor(), |
| checkedContentColor: Color = contentColorFor(checkedContainerColor) |
| ): IconToggleButtonColors = |
| DefaultIconToggleButtonColors( |
| containerColor = containerColor, |
| contentColor = contentColor, |
| disabledContainerColor = disabledContainerColor, |
| disabledContentColor = disabledContentColor, |
| checkedContainerColor = checkedContainerColor, |
| checkedContentColor = checkedContentColor, |
| ) |
| |
| /** |
| * Represents the [BorderStroke] for an [OutlinedIconButton], depending on its [enabled] and |
| * [checked] state. |
| * |
| * @param enabled whether the icon button is enabled |
| * @param checked whether the icon button is checked |
| */ |
| @Composable |
| fun outlinedIconToggleButtonBorder(enabled: Boolean, checked: Boolean): BorderStroke? { |
| if (checked) { |
| return null |
| } |
| return outlinedIconButtonBorder(enabled) |
| } |
| |
| /** |
| * Represents the [BorderStroke] for an [OutlinedIconButton], depending on its [enabled] state. |
| * |
| * @param enabled whether the icon button is enabled |
| */ |
| @Composable |
| fun outlinedIconButtonBorder(enabled: Boolean): BorderStroke { |
| val color: Color = if (enabled) { |
| LocalContentColor.current |
| } else { |
| LocalContentColor.current |
| .copy(alpha = OutlinedIconButtonTokens.DisabledOutlineOpacity) |
| } |
| return remember(color) { |
| BorderStroke(OutlinedIconButtonTokens.UnselectedOutlineWidth, color) |
| } |
| } |
| } |
| |
| /** |
| * Default [IconButtonColors] implementation. |
| */ |
| @Immutable |
| private class DefaultIconButtonColors( |
| private val containerColor: Color, |
| private val contentColor: Color, |
| private val disabledContainerColor: Color, |
| private val disabledContentColor: Color, |
| ) : IconButtonColors { |
| @Composable |
| override fun containerColor(enabled: Boolean): State<Color> { |
| return rememberUpdatedState(if (enabled) containerColor else disabledContainerColor) |
| } |
| |
| @Composable |
| override fun contentColor(enabled: Boolean): State<Color> { |
| return rememberUpdatedState(if (enabled) contentColor else disabledContentColor) |
| } |
| |
| override fun equals(other: Any?): Boolean { |
| if (this === other) return true |
| if (other == null || this::class != other::class) return false |
| |
| other as DefaultIconButtonColors |
| |
| if (containerColor != other.containerColor) return false |
| if (contentColor != other.contentColor) return false |
| if (disabledContainerColor != other.disabledContainerColor) return false |
| if (disabledContentColor != other.disabledContentColor) return false |
| |
| return true |
| } |
| |
| override fun hashCode(): Int { |
| var result = containerColor.hashCode() |
| result = 31 * result + contentColor.hashCode() |
| result = 31 * result + disabledContainerColor.hashCode() |
| result = 31 * result + disabledContentColor.hashCode() |
| |
| return result |
| } |
| } |
| |
| /** |
| * Default [IconToggleButtonColors] implementation. |
| */ |
| @Immutable |
| private class DefaultIconToggleButtonColors( |
| private val containerColor: Color, |
| private val contentColor: Color, |
| private val disabledContainerColor: Color, |
| private val disabledContentColor: Color, |
| private val checkedContainerColor: Color, |
| private val checkedContentColor: Color, |
| ) : IconToggleButtonColors { |
| @Composable |
| override fun containerColor(enabled: Boolean, checked: Boolean): State<Color> { |
| val target = when { |
| !enabled -> disabledContainerColor |
| !checked -> containerColor |
| else -> checkedContainerColor |
| } |
| return rememberUpdatedState(target) |
| } |
| |
| @Composable |
| override fun contentColor(enabled: Boolean, checked: Boolean): State<Color> { |
| val target = when { |
| !enabled -> disabledContentColor |
| !checked -> contentColor |
| else -> checkedContentColor |
| } |
| return rememberUpdatedState(target) |
| } |
| |
| override fun equals(other: Any?): Boolean { |
| if (this === other) return true |
| if (other == null || this::class != other::class) return false |
| |
| other as DefaultIconToggleButtonColors |
| |
| if (containerColor != other.containerColor) return false |
| if (contentColor != other.contentColor) return false |
| if (disabledContainerColor != other.disabledContainerColor) return false |
| if (disabledContentColor != other.disabledContentColor) return false |
| if (checkedContainerColor != other.checkedContainerColor) return false |
| if (checkedContentColor != other.checkedContentColor) return false |
| |
| return true |
| } |
| |
| override fun hashCode(): Int { |
| var result = containerColor.hashCode() |
| result = 31 * result + contentColor.hashCode() |
| result = 31 * result + disabledContainerColor.hashCode() |
| result = 31 * result + disabledContentColor.hashCode() |
| result = 31 * result + checkedContainerColor.hashCode() |
| result = 31 * result + checkedContentColor.hashCode() |
| |
| return result |
| } |
| } |