Skip to content

Commit

Permalink
Merge pull request #58 from gabrieldrn/component/dropdown-hover-click…
Browse files Browse the repository at this point in the history
…-states

Dropdown click states
  • Loading branch information
gabrieldrn authored Feb 20, 2025
2 parents 566c08f + 236be39 commit 3aafe32
Show file tree
Hide file tree
Showing 18 changed files with 237 additions and 84 deletions.
21 changes: 19 additions & 2 deletions carbon/api/android/carbon.api
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,6 @@ public final class com/gabrieldrn/carbon/foundation/color/Layer : java/lang/Enum
public abstract class com/gabrieldrn/carbon/foundation/color/Theme {
public static final field $stable I
public fun <init> ()V
public final fun containerColor-vNxB06k (Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun containerColor-vNxB06k$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static synthetic fun copy-2-eky90$carbon_release$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJLcom/gabrieldrn/carbon/foundation/color/ai/AiColors;Lcom/gabrieldrn/carbon/foundation/color/button/ButtonColors;Lcom/gabrieldrn/carbon/foundation/color/chat/ChatColors;Lcom/gabrieldrn/carbon/foundation/color/notification/NotificationColors;Lcom/gabrieldrn/carbon/foundation/color/tag/TagColors;IIIILjava/lang/Object;)Lcom/gabrieldrn/carbon/foundation/color/Theme;
public fun equals (Ljava/lang/Object;)Z
public abstract fun getAiColors ()Lcom/gabrieldrn/carbon/foundation/color/ai/AiColors;
Expand Down Expand Up @@ -673,6 +671,25 @@ public abstract class com/gabrieldrn/carbon/foundation/color/Theme {
public fun hashCode ()I
}

public final class com/gabrieldrn/carbon/foundation/color/ThemeExtKt {
public static final fun containerColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun containerColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerAccentActiveColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerAccentActiveColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerAccentColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerAccentColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerAccentHoverColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerAccentHoverColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerActiveColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerActiveColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerHoverColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerHoverColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerSelectedColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerSelectedColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerSelectedHoverColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerSelectedHoverColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
}

public final class com/gabrieldrn/carbon/foundation/color/ThemeStaticCompositionKt {
public static final fun CarbonLayer (Lcom/gabrieldrn/carbon/foundation/color/Layer;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
public static final fun CarbonLayer (Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
Expand Down
21 changes: 19 additions & 2 deletions carbon/api/desktop/carbon.api
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,6 @@ public final class com/gabrieldrn/carbon/foundation/color/Layer : java/lang/Enum
public abstract class com/gabrieldrn/carbon/foundation/color/Theme {
public static final field $stable I
public fun <init> ()V
public final fun containerColor-vNxB06k (Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun containerColor-vNxB06k$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static synthetic fun copy-2-eky90$carbon$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJLcom/gabrieldrn/carbon/foundation/color/ai/AiColors;Lcom/gabrieldrn/carbon/foundation/color/button/ButtonColors;Lcom/gabrieldrn/carbon/foundation/color/chat/ChatColors;Lcom/gabrieldrn/carbon/foundation/color/notification/NotificationColors;Lcom/gabrieldrn/carbon/foundation/color/tag/TagColors;IIIILjava/lang/Object;)Lcom/gabrieldrn/carbon/foundation/color/Theme;
public fun equals (Ljava/lang/Object;)Z
public abstract fun getAiColors ()Lcom/gabrieldrn/carbon/foundation/color/ai/AiColors;
Expand Down Expand Up @@ -673,6 +671,25 @@ public abstract class com/gabrieldrn/carbon/foundation/color/Theme {
public fun hashCode ()I
}

public final class com/gabrieldrn/carbon/foundation/color/ThemeExtKt {
public static final fun containerColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun containerColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerAccentActiveColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerAccentActiveColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerAccentColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerAccentColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerAccentHoverColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerAccentHoverColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerActiveColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerActiveColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerHoverColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerHoverColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerSelectedColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerSelectedColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
public static final fun layerSelectedHoverColor (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;)J
public static synthetic fun layerSelectedHoverColor$default (Lcom/gabrieldrn/carbon/foundation/color/Theme;Lcom/gabrieldrn/carbon/foundation/color/Layer;ILjava/lang/Object;)J
}

public final class com/gabrieldrn/carbon/foundation/color/ThemeStaticCompositionKt {
public static final fun CarbonLayer (Lcom/gabrieldrn/carbon/foundation/color/Layer;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
public static final fun CarbonLayer (Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;I)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.gabrieldrn.carbon.dropdown

import androidx.compose.animation.core.MutableTransitionState
import androidx.compose.animation.core.rememberTransition
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
Expand All @@ -39,6 +38,7 @@ import com.gabrieldrn.carbon.dropdown.base.DropdownSize
import com.gabrieldrn.carbon.dropdown.base.DropdownStateIcon
import com.gabrieldrn.carbon.foundation.color.CarbonLayer
import com.gabrieldrn.carbon.foundation.color.Layer
import com.gabrieldrn.carbon.foundation.color.containerColor
import com.gabrieldrn.carbon.foundation.spacing.SpacingScale

private class DropdownLayerPreviewParameterProvider : PreviewParameterProvider<Layer> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import androidx.compose.ui.graphics.Color
import com.gabrieldrn.carbon.Carbon
import com.gabrieldrn.carbon.foundation.color.Layer
import com.gabrieldrn.carbon.foundation.color.Theme
import com.gabrieldrn.carbon.foundation.color.layerActiveColor
import com.gabrieldrn.carbon.foundation.color.layerHoverColor
import com.gabrieldrn.carbon.foundation.color.layerSelectedColor
import com.gabrieldrn.carbon.foundation.color.layerSelectedHoverColor

/**
* The colors used by the dropdown composable based on the current [theme].
Expand Down Expand Up @@ -121,15 +125,18 @@ internal class DropdownColors private constructor(
)

@Composable
fun menuOptionBackgroundSelectedColor(isSelected: Boolean): State<Color> =
fun menuOptionBackground(
isSelected: Boolean,
isHovered: Boolean,
isActive: Boolean
): State<Color> =
rememberUpdatedState(
newValue = with(theme) {
if (isSelected) when (layer) {
Layer.Layer00 -> layerSelected01
Layer.Layer01 -> layerSelected02
else -> layerSelected03
}
else Color.Transparent
newValue = when {
isActive -> theme.layerActiveColor(layer)
!isSelected && isHovered -> theme.layerHoverColor(layer)
isSelected && isHovered -> theme.layerSelectedHoverColor(layer)
isSelected -> theme.layerSelectedColor(layer)
else -> Color.Transparent
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package com.gabrieldrn.carbon.dropdown.base
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
Expand Down Expand Up @@ -139,8 +141,13 @@ private fun DropdownMenuOption(
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
val menuOptionBackgroundSelectedColor by colors.menuOptionBackgroundSelectedColor(
isSelected = isSelected
val isHovered by interactionSource.collectIsHoveredAsState()
val isPressed by interactionSource.collectIsPressedAsState()

val menuOptionBackgroundSelectedColor by colors.menuOptionBackground(
isSelected = isSelected,
isHovered = isHovered,
isActive = isPressed
)

val menuOptionTextColor by colors.menuOptionTextColor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ package com.gabrieldrn.carbon.dropdown.multiselect

import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
Expand Down Expand Up @@ -136,10 +138,14 @@ private fun MultiselectDropdownMenuOption(
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
val menuOptionBackgroundSelectedColor by colors.menuOptionBackgroundSelectedColor(
isSelected = isSelected
)
val isHovered by interactionSource.collectIsHoveredAsState()
val isPressed by interactionSource.collectIsPressedAsState()

val menuOptionBackgroundSelectedColor by colors.menuOptionBackground(
isSelected = isSelected,
isHovered = isHovered,
isActive = isPressed
)
val menuOptionTextColor by colors.menuOptionTextColor(
isEnabled = option.enabled,
isSelected = isSelected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import com.gabrieldrn.carbon.foundation.color.button.ButtonColors
import com.gabrieldrn.carbon.foundation.color.chat.ChatColors
import com.gabrieldrn.carbon.foundation.color.notification.NotificationColors
import com.gabrieldrn.carbon.foundation.color.tag.TagColors
import kotlin.Any
import kotlin.Boolean
import kotlin.Int
import kotlin.Suppress

/**
* Themes are used to modify existing components to fit a specific visual style. By using Carbon’s
Expand Down Expand Up @@ -241,18 +237,6 @@ public abstract class Theme {

public abstract val tagColors: TagColors

/**
* Returns the container color based on a provided [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun containerColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> background
Layer.Layer01 -> layer01
Layer.Layer02 -> layer02
Layer.Layer03 -> layer03
}

@Suppress("LongMethod")
internal fun copy(
background: Color = this.background,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2025 Gabriel Derrien
*
* 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 com.gabrieldrn.carbon.foundation.color

import androidx.compose.ui.graphics.Color

/**
* Returns the container color based on a provided [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.containerColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> background
Layer.Layer01 -> layer01
Layer.Layer02 -> layer02
Layer.Layer03 -> layer03
}

/**
* Returns the `layer-active` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerActiveColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerActive01
Layer.Layer01 -> layerActive02
else -> layerActive03
}

/**
* Returns the `layer-hover` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerHoverColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerHover01
Layer.Layer01 -> layerHover02
else -> layerHover03
}

/**
* Returns the `layer-selected` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerSelectedColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerSelected01
Layer.Layer01 -> layerSelected02
else -> layerSelected03
}

/**
* Returns the `layer-selected-hover` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerSelectedHoverColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerSelectedHover01
Layer.Layer01 -> layerSelectedHover02
else -> layerSelectedHover03
}

/**
* Returns the `layer-accent` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerAccentColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerAccent01
Layer.Layer01 -> layerAccent02
else -> layerAccent03
}

/**
* Returns the `layer-accent-hover` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerAccentHoverColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerAccentHover01
Layer.Layer01 -> layerAccentHover02
else -> layerAccentHover03
}

/**
* Returns the `layer-accent-active` color from this [Theme] based on the current [layer].
*
* @param layer Associated layer. Defaults to layer 00.
*/
public fun Theme.layerAccentActiveColor(layer: Layer = Layer.Layer00): Color = when (layer) {
Layer.Layer00 -> layerAccentActive01
Layer.Layer01 -> layerAccentActive02
else -> layerAccentActive03
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,4 @@ private fun DrawScope.drawSeparator(
topLeft = Offset(size.width - 1.dp.toPx(), 0f),
size = Size(width = 1.dp.toPx(), height = size.height)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@ internal class TabColors private constructor(
@Composable
fun colors(variant: TabVariant) = TabColors(Carbon.theme, Carbon.layer, variant)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import androidx.compose.ui.unit.dp
import com.gabrieldrn.carbon.Carbon
import com.gabrieldrn.carbon.button.ButtonType
import com.gabrieldrn.carbon.button.IconButton
import com.gabrieldrn.carbon.foundation.color.containerColor
import com.gabrieldrn.carbon.icons.chevronLeftIcon
import com.gabrieldrn.carbon.icons.chevronRightIcon
import kotlinx.coroutines.CoroutineScope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ package com.gabrieldrn.carbon.tab

internal object TabListTestTags {
const val TAB_ROOT = "carbon_tab_root"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ public enum class TabVariant(
* An emphasized tab that is commonly used for defined content areas.
*/
Contained(height = SpacingScale.spacing09)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,25 @@ abstract class BaseColorsTest {
}
}
}

protected fun <T : Any, U : Any, V : Any> ComposeUiTest.forAllLayersAndStates(
statesUnderTest1: Collection<T>,
statesUnderTest2: Collection<U>,
statesUnderTest3: Collection<V>,
block: @Composable (state1: T, state2: U, state3: V, layer: Layer) -> Unit
) {
setContent {
statesUnderTest1.forEach { state1 ->
statesUnderTest2.forEach { state2 ->
statesUnderTest3.forEach { state3 ->
Layer.entries.forEach { layer ->
CarbonDesignSystem(theme = theme, layer = layer) {
block(state1, state2, state3, layer)
}
}
}
}
}
}
}
}
Loading

0 comments on commit 3aafe32

Please sign in to comment.