From bc358d4e34d927a3e19de88de3561dcf44570271 Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Fri, 25 Oct 2024 12:59:58 +0200 Subject: [PATCH] Polish TextField, TextArea, and RadioButton (#662) * Prefer Unspecified over Transparent for colours in bridge * Align standalone text field/area styling to bridge * Align standalone radio button icon gap to bridge * Improve text area/field standalone samples to include readOnly --- .../jewel/bridge/theme/IntUiBridge.kt | 24 +-- .../styling/IntUiRadioButtonStyling.kt | 2 +- .../styling/IntUiTextAreaStyling.kt | 4 +- .../styling/IntUiTextFieldStyling.kt | 4 +- .../standalone/view/component/TextAreas.kt | 102 +++++++++---- .../standalone/view/component/TextFields.kt | 139 +++++++++++------- 6 files changed, 180 insertions(+), 95 deletions(-) diff --git a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt index 74611408d..4b1a123fc 100644 --- a/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt +++ b/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt @@ -552,11 +552,11 @@ private fun readUndecoratedDropdownStyle(menuStyle: MenuStyle): DropdownStyle { contentFocused = normalContent, contentPressed = normalContent, contentHovered = normalContent, - border = Color.Transparent, - borderDisabled = Color.Transparent, - borderFocused = Color.Transparent, - borderPressed = Color.Transparent, - borderHovered = Color.Transparent, + border = Color.Unspecified, + borderDisabled = Color.Unspecified, + borderFocused = Color.Unspecified, + borderPressed = Color.Unspecified, + borderHovered = Color.Unspecified, iconTint = Color.Unspecified, iconTintDisabled = Color.Unspecified, iconTintFocused = Color.Unspecified, @@ -903,7 +903,7 @@ private fun readTextAreaStyle(metrics: TextFieldMetrics): TextAreaStyle { val colors = TextAreaColors( background = normalBackground, - backgroundDisabled = Color.Transparent, + backgroundDisabled = Color.Unspecified, backgroundFocused = normalBackground, backgroundPressed = normalBackground, backgroundHovered = normalBackground, @@ -947,7 +947,7 @@ private fun readTextFieldStyle(): TextFieldStyle { val colors = TextFieldColors( background = normalBackground, - backgroundDisabled = Color.Transparent, + backgroundDisabled = Color.Unspecified, backgroundFocused = normalBackground, backgroundPressed = normalBackground, backgroundHovered = normalBackground, @@ -994,7 +994,7 @@ private fun readLazyTreeStyle(): LazyTreeStyle { contentFocused = normalContent, contentSelected = selectedContent, contentSelectedFocused = selectedContent, - elementBackgroundFocused = Color.Transparent, + elementBackgroundFocused = Color.Unspecified, elementBackgroundSelected = inactiveSelectedElementBackground, elementBackgroundSelectedFocused = selectedElementBackground, ) @@ -1042,10 +1042,10 @@ private fun readDefaultTabStyle(): TabStyle { contentPressed = normalContent, contentHovered = normalContent, contentSelected = normalContent, - underline = Color.Transparent, + underline = Color.Unspecified, underlineDisabled = retrieveColorOrUnspecified("TabbedPane.disabledUnderlineColor"), underlinePressed = selectedUnderline, - underlineHovered = Color.Transparent, + underlineHovered = Color.Unspecified, underlineSelected = selectedUnderline, ) @@ -1095,10 +1095,10 @@ private fun readEditorTabStyle(): TabStyle { contentPressed = normalContent, contentHovered = normalContent, contentSelected = normalContent, - underline = Color.Transparent, + underline = Color.Unspecified, underlineDisabled = retrieveColorOrUnspecified("TabbedPane.disabledUnderlineColor"), underlinePressed = selectedUnderline, - underlineHovered = Color.Transparent, + underlineHovered = Color.Unspecified, underlineSelected = selectedUnderline, ) diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt index d5e617aae..10440291f 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiRadioButtonStyling.kt @@ -70,7 +70,7 @@ public fun RadioButtonMetrics.Companion.defaults( outlineFocusedSize: DpSize = outlineSize, outlineSelectedSize: DpSize = DpSize(22.dp, 22.dp), outlineSelectedFocusedSize: DpSize = outlineSelectedSize, - iconContentGap: Dp = 8.dp, + iconContentGap: Dp = 4.dp, ): RadioButtonMetrics = RadioButtonMetrics( radioButtonSize = radioButtonSize, diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt index bfc95fce4..944b051a1 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextAreaStyling.kt @@ -28,7 +28,7 @@ public fun TextAreaStyle.Companion.dark( @Composable public fun TextAreaColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), - backgroundDisabled: Color = IntUiLightTheme.colors.gray(13), + backgroundDisabled: Color = Color.Unspecified, backgroundFocused: Color = background, backgroundPressed: Color = background, backgroundHovered: Color = background, @@ -76,7 +76,7 @@ public fun TextAreaColors.Companion.light( @Composable public fun TextAreaColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), - backgroundDisabled: Color = background, + backgroundDisabled: Color = Color.Unspecified, backgroundFocused: Color = background, backgroundPressed: Color = background, backgroundHovered: Color = background, diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt index 32ef15589..4e2c6ee8c 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTextFieldStyling.kt @@ -28,7 +28,7 @@ public fun TextFieldStyle.Companion.dark( @Composable public fun TextFieldColors.Companion.light( background: Color = IntUiLightTheme.colors.gray(14), - backgroundDisabled: Color = IntUiLightTheme.colors.gray(13), + backgroundDisabled: Color = Color.Unspecified, backgroundFocused: Color = background, backgroundPressed: Color = background, backgroundHovered: Color = background, @@ -76,7 +76,7 @@ public fun TextFieldColors.Companion.light( @Composable public fun TextFieldColors.Companion.dark( background: Color = IntUiDarkTheme.colors.gray(2), - backgroundDisabled: Color = background, + backgroundDisabled: Color = Color.Unspecified, backgroundFocused: Color = background, backgroundPressed: Color = background, backgroundHovered: Color = background, diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt index aae824e1e..b0a15a13a 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextAreas.kt @@ -1,8 +1,11 @@ package org.jetbrains.jewel.samples.standalone.view.component import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.input.rememberTextFieldState @@ -11,8 +14,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import org.jetbrains.jewel.ui.Outline +import org.jetbrains.jewel.ui.component.GroupHeader import org.jetbrains.jewel.ui.component.Text import org.jetbrains.jewel.ui.component.TextArea +import org.jetbrains.jewel.ui.component.VerticallyScrollableContainer @Suppress("SpellCheckingInspection") private const val LOREM_IPSUM = @@ -30,31 +35,76 @@ private const val LOREM_IPSUM = @Composable fun TextAreas() { - Row( - Modifier.padding(horizontal = 16.dp).height(200.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.Top, - ) { - TextArea(state = rememberTextFieldState(LOREM_IPSUM), modifier = Modifier.weight(1f).fillMaxHeight()) - - TextArea( - state = rememberTextFieldState(LOREM_IPSUM), - modifier = Modifier.weight(1f).fillMaxHeight(), - enabled = false, - ) - - TextArea( - state = rememberTextFieldState(""), - modifier = Modifier.weight(1f).fillMaxHeight(), - outline = Outline.Error, - placeholder = { Text("Text area with error") }, - ) - - TextArea( - state = rememberTextFieldState(""), - modifier = Modifier.weight(1f).fillMaxHeight(), - outline = Outline.Warning, - placeholder = { Text("Text area with warning") }, - ) + VerticallyScrollableContainer(Modifier.fillMaxSize()) { + Column(Modifier.padding(vertical = 4.dp)) { + Row( + Modifier.padding(horizontal = 16.dp).height(200.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.Top, + ) { + TextArea(state = rememberTextFieldState(LOREM_IPSUM), modifier = Modifier.weight(1f).fillMaxHeight()) + + TextArea( + state = rememberTextFieldState(LOREM_IPSUM), + modifier = Modifier.weight(1f).fillMaxHeight(), + enabled = false, + ) + + TextArea( + state = rememberTextFieldState(""), + modifier = Modifier.weight(1f).fillMaxHeight(), + outline = Outline.Error, + placeholder = { Text("Text area with error") }, + ) + + TextArea( + state = rememberTextFieldState(""), + modifier = Modifier.weight(1f).fillMaxHeight(), + outline = Outline.Warning, + placeholder = { Text("Text area with warning") }, + ) + } + + Spacer(Modifier.height(16.dp)) + + GroupHeader("Read-only") + + Spacer(Modifier.height(16.dp)) + + Row( + Modifier.padding(horizontal = 16.dp).height(200.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.Top, + ) { + TextArea( + state = rememberTextFieldState(LOREM_IPSUM), + modifier = Modifier.weight(1f).fillMaxHeight(), + readOnly = true, + ) + + TextArea( + state = rememberTextFieldState(LOREM_IPSUM), + modifier = Modifier.weight(1f).fillMaxHeight(), + enabled = false, + readOnly = true, + ) + + TextArea( + state = rememberTextFieldState("Error state"), + modifier = Modifier.weight(1f).fillMaxHeight(), + outline = Outline.Error, + placeholder = { Text("Text area with error") }, + readOnly = true, + ) + + TextArea( + state = rememberTextFieldState("Warning state"), + modifier = Modifier.weight(1f).fillMaxHeight(), + outline = Outline.Warning, + placeholder = { Text("Text area with warning") }, + readOnly = true, + ) + } + } } } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt index 1c912ec6d..0d18f89ad 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/TextFields.kt @@ -7,7 +7,12 @@ import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.text.input.rememberTextFieldState @@ -26,10 +31,12 @@ import org.jetbrains.jewel.intui.standalone.styling.defaults import org.jetbrains.jewel.intui.standalone.styling.light import org.jetbrains.jewel.samples.standalone.StandaloneSampleIcons import org.jetbrains.jewel.ui.Outline +import org.jetbrains.jewel.ui.component.GroupHeader import org.jetbrains.jewel.ui.component.Icon import org.jetbrains.jewel.ui.component.IconButton import org.jetbrains.jewel.ui.component.Text import org.jetbrains.jewel.ui.component.TextField +import org.jetbrains.jewel.ui.component.VerticallyScrollableContainer import org.jetbrains.jewel.ui.component.styling.IconButtonColors import org.jetbrains.jewel.ui.component.styling.IconButtonMetrics import org.jetbrains.jewel.ui.component.styling.IconButtonStyle @@ -38,63 +45,91 @@ import org.jetbrains.jewel.ui.painter.hints.Stateful @Composable fun TextFields() { - Row(horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically) { - val state1 = rememberTextFieldState("TextField") - TextField(state = state1, modifier = Modifier.width(200.dp)) - - val state2 = rememberTextFieldState("") - TextField(state = state2, placeholder = { Text("Placeholder") }, modifier = Modifier.width(200.dp)) - - val state3 = rememberTextFieldState("") - TextField( - state = state3, - outline = Outline.Error, - placeholder = { Text("Error outline") }, - modifier = Modifier.width(200.dp), - ) - } + VerticallyScrollableContainer(Modifier.fillMaxSize()) { + Column { + TextFieldsRows(readOnly = false) - Row(horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically) { - val state1 = rememberTextFieldState("") - TextField( - state = state1, - outline = Outline.Warning, - placeholder = { Text("Warning outline") }, - modifier = Modifier.width(200.dp), - ) + Spacer(Modifier.height(16.dp)) + + GroupHeader("Read-only") + + Spacer(Modifier.height(16.dp)) - val state2 = rememberTextFieldState("Disabled") - TextField(state = state2, enabled = false, modifier = Modifier.width(200.dp)) + TextFieldsRows(readOnly = true) + } } +} - Row(horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.Top) { - val state1 = rememberTextFieldState("") - TextField( - state = state1, - placeholder = { Text("With leading icon") }, - modifier = Modifier.width(200.dp), - leadingIcon = { - Icon( - key = AllIconsKeys.Actions.Find, - contentDescription = "SearchIcon", - iconClass = StandaloneSampleIcons::class.java, - modifier = Modifier.size(16.dp), - ) - }, - ) +@Composable +private fun TextFieldsRows(readOnly: Boolean) { + Column(modifier = Modifier.padding(vertical = 4.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { + Row(horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically) { + val state1 = rememberTextFieldState("TextField") + TextField(state = state1, modifier = Modifier.width(200.dp), readOnly = readOnly) - val state2 = rememberTextFieldState("") - TextField( - state = state2, - placeholder = { Text("With trailing button") }, - modifier = Modifier.width(200.dp), - trailingIcon = { - CloseIconButton( - isVisible = state2.text.isNotEmpty(), - onClick = { state2.setTextAndPlaceCursorAtEnd("") }, - ) - }, - ) + val state2 = rememberTextFieldState("") + TextField( + state = state2, + placeholder = { Text("Placeholder") }, + modifier = Modifier.width(200.dp), + readOnly = readOnly, + ) + + val state3 = rememberTextFieldState("") + TextField( + state = state3, + outline = Outline.Error, + placeholder = { Text("Error outline") }, + modifier = Modifier.width(200.dp), + readOnly = readOnly, + ) + } + + Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically) { + val state1 = rememberTextFieldState("") + TextField( + state = state1, + outline = Outline.Warning, + placeholder = { Text("Warning outline") }, + modifier = Modifier.width(200.dp), + readOnly = readOnly, + ) + + val state2 = rememberTextFieldState("Disabled") + TextField(state = state2, enabled = false, modifier = Modifier.width(200.dp), readOnly = readOnly) + } + + Row(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.Top) { + val state1 = rememberTextFieldState("") + TextField( + state = state1, + placeholder = { Text("With leading icon") }, + modifier = Modifier.width(200.dp), + leadingIcon = { + Icon( + key = AllIconsKeys.Actions.Find, + contentDescription = "SearchIcon", + iconClass = StandaloneSampleIcons::class.java, + modifier = Modifier.size(16.dp), + ) + }, + readOnly = readOnly, + ) + + val state2 = rememberTextFieldState("") + TextField( + state = state2, + placeholder = { Text("With trailing button") }, + modifier = Modifier.width(200.dp), + trailingIcon = { + CloseIconButton( + isVisible = state2.text.isNotEmpty(), + onClick = { state2.setTextAndPlaceCursorAtEnd("") }, + ) + }, + readOnly = readOnly, + ) + } } }