From 9a24684581d408689708978b38c49cb9b4575a30 Mon Sep 17 00:00:00 2001 From: Ivan Morgillo Date: Wed, 7 Aug 2024 12:51:07 +0200 Subject: [PATCH] Clean up work on scrollbars (#521) * # Conflicts: # samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Scrollbars.kt * stitch wrong import after rebase Signed-off-by: Ivan Morgillo * reformat according to feedback Signed-off-by: Ivan Morgillo --------- Signed-off-by: Ivan Morgillo --- .idea/inspectionProfiles/Project_Default.xml | 4 +- .../api/int-ui-standalone.api | 33 +++- .../styling/IntUiScrollbarStyling.kt | 155 ++++++++++++++---- .../standalone/styling/IntUiTabStyling.kt | 9 +- .../samples/ideplugin/ComponentShowcaseTab.kt | 6 +- .../ideplugin/JewelDemoToolWindowFactory.kt | 4 + .../ideplugin/ScrollbarsShowcaseTab.kt | 117 +++++++++++++ .../ideplugin/SwingComparisonTabPanel.kt | 22 ++- .../releasessample/ReleasesSampleCompose.kt | 10 +- .../standalone/view/component/Scrollbars.kt | 8 +- .../standalone/view/component/TextAreas.kt | 28 ++-- .../standalone/view/component/TextFields.kt | 77 ++++++--- .../view/markdown/MarkdownEditor.kt | 12 +- ui/api/ui.api | 2 + .../jewel/ui/component/InputField.kt | 118 ++++++++++++- .../jewel/ui/component/Scrollbars.kt | 11 +- .../jetbrains/jewel/ui/component/TabStrip.kt | 28 ++-- .../jetbrains/jewel/ui/component/TextArea.kt | 56 ++++++- .../jetbrains/jewel/ui/component/TextField.kt | 55 +++++++ 19 files changed, 620 insertions(+), 135 deletions(-) create mode 100644 samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ScrollbarsShowcaseTab.kt diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index b4208d4d7..410449b81 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -11,9 +11,9 @@ - + - \ No newline at end of file + diff --git a/int-ui/int-ui-standalone/api/int-ui-standalone.api b/int-ui/int-ui-standalone/api/int-ui-standalone.api index d562c495e..96ada1ff4 100644 --- a/int-ui/int-ui-standalone/api/int-ui-standalone.api +++ b/int-ui/int-ui-standalone/api/int-ui-standalone.api @@ -117,7 +117,8 @@ public final class org/jetbrains/jewel/intui/standalone/styling/IntUiDefaultTabS public static final field $stable I public static final field INSTANCE Lorg/jetbrains/jewel/intui/standalone/styling/IntUiDefaultTabStyleFactory; public final fun dark (Lorg/jetbrains/jewel/ui/component/styling/TabColors;Lorg/jetbrains/jewel/ui/component/styling/TabMetrics;Lorg/jetbrains/jewel/ui/component/styling/TabIcons;Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Landroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/styling/TabStyle; - public final fun light (Lorg/jetbrains/jewel/ui/component/styling/TabColors;Lorg/jetbrains/jewel/ui/component/styling/TabMetrics;Lorg/jetbrains/jewel/ui/component/styling/TabIcons;Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;Landroidx/compose/runtime/Composer;II)Lorg/jetbrains/jewel/ui/component/styling/TabStyle; + public final fun light (Lorg/jetbrains/jewel/ui/component/styling/TabColors;Lorg/jetbrains/jewel/ui/component/styling/TabMetrics;Lorg/jetbrains/jewel/ui/component/styling/TabIcons;Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;)Lorg/jetbrains/jewel/ui/component/styling/TabStyle; + public static synthetic fun light$default (Lorg/jetbrains/jewel/intui/standalone/styling/IntUiDefaultTabStyleFactory;Lorg/jetbrains/jewel/ui/component/styling/TabColors;Lorg/jetbrains/jewel/ui/component/styling/TabMetrics;Lorg/jetbrains/jewel/ui/component/styling/TabIcons;Lorg/jetbrains/jewel/ui/component/styling/TabContentAlpha;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/TabStyle; } public final class org/jetbrains/jewel/intui/standalone/styling/IntUiDividerStyleKt { @@ -270,16 +271,30 @@ public final class org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarSt public static synthetic fun macOsLight$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; public static final fun macOsLight-iLRpYWo (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; public static synthetic fun macOsLight-iLRpYWo$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; - public static final fun winOsDark (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; - public static synthetic fun winOsDark$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; - public static final fun winOsDark-iLRpYWo (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; - public static synthetic fun winOsDark-iLRpYWo$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; - public static final fun winOsLight (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; - public static synthetic fun winOsLight$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; - public static final fun winOsLight-iLRpYWo (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; - public static synthetic fun winOsLight-iLRpYWo$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; + public static final fun tabStripDark (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun tabStripLight (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun tabStripMacOs-VkLD3kw (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics$Companion;Landroidx/compose/foundation/shape/CornerSize;FFLandroidx/compose/foundation/layout/PaddingValues;FLandroidx/compose/foundation/layout/PaddingValues;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics; + public static synthetic fun tabStripMacOs-VkLD3kw$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics$Companion;Landroidx/compose/foundation/shape/CornerSize;FFLandroidx/compose/foundation/layout/PaddingValues;FLandroidx/compose/foundation/layout/PaddingValues;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics; + public static final fun tabStripMacOsDark (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static synthetic fun tabStripMacOsDark$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun tabStripMacOsLight (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static synthetic fun tabStripMacOsLight$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun tabStripWindowsAndLinux-VkLD3kw (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics$Companion;Landroidx/compose/foundation/shape/CornerSize;FFLandroidx/compose/foundation/layout/PaddingValues;FLandroidx/compose/foundation/layout/PaddingValues;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics; + public static synthetic fun tabStripWindowsAndLinux-VkLD3kw$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics$Companion;Landroidx/compose/foundation/shape/CornerSize;FFLandroidx/compose/foundation/layout/PaddingValues;FLandroidx/compose/foundation/layout/PaddingValues;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics; + public static final fun tabStripWindowsAndLinuxDark (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static synthetic fun tabStripWindowsAndLinuxDark$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun tabStripWindowsAndLinuxLight (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static synthetic fun tabStripWindowsAndLinuxLight$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; public static final fun windows-VkLD3kw (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics$Companion;Landroidx/compose/foundation/shape/CornerSize;FFLandroidx/compose/foundation/layout/PaddingValues;FLandroidx/compose/foundation/layout/PaddingValues;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics; public static synthetic fun windows-VkLD3kw$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics$Companion;Landroidx/compose/foundation/shape/CornerSize;FFLandroidx/compose/foundation/layout/PaddingValues;FLandroidx/compose/foundation/layout/PaddingValues;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics; + public static final fun windowsAndLinuxDark (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static synthetic fun windowsAndLinuxDark$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun windowsAndLinuxDark-iLRpYWo (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; + public static synthetic fun windowsAndLinuxDark-iLRpYWo$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; + public static final fun windowsAndLinuxLight (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static synthetic fun windowsAndLinuxLight$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle$Companion;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarMetrics;Lorg/jetbrains/jewel/ui/component/styling/TrackClickBehavior;Lorg/jetbrains/jewel/ui/component/styling/ScrollbarVisibility;ILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarStyle; + public static final fun windowsAndLinuxLight-iLRpYWo (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJ)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; + public static synthetic fun windowsAndLinuxLight-iLRpYWo$default (Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors$Companion;JJJJJJJJILjava/lang/Object;)Lorg/jetbrains/jewel/ui/component/styling/ScrollbarColors; } public final class org/jetbrains/jewel/intui/standalone/styling/IntUiSegmentedControlButtonStylingKt { diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt index 9d91b16b6..c406c34d3 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiScrollbarStyling.kt @@ -14,9 +14,23 @@ import org.jetbrains.skiko.hostOs import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds +public fun ScrollbarStyle.Companion.dark(): ScrollbarStyle = + if (hostOs.isMacOS) { + ScrollbarStyle.macOsDark() + } else { + ScrollbarStyle.windowsAndLinuxDark() + } + +public fun ScrollbarStyle.Companion.light(): ScrollbarStyle = + if (hostOs.isMacOS) { + ScrollbarStyle.macOsLight() + } else { + ScrollbarStyle.windowsAndLinuxLight() + } + public fun ScrollbarStyle.Companion.macOsLight( colors: ScrollbarColors = ScrollbarColors.macOsLight(), - metrics: ScrollbarMetrics = provideScrollbarMetrics(), + metrics: ScrollbarMetrics = ScrollbarMetrics.macOs(), trackClickBehavior: TrackClickBehavior = TrackClickBehavior.NextPage, scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.WhenScrolling.defaults(), ): ScrollbarStyle = @@ -29,7 +43,7 @@ public fun ScrollbarStyle.Companion.macOsLight( public fun ScrollbarStyle.Companion.macOsDark( colors: ScrollbarColors = ScrollbarColors.macOsDark(), - metrics: ScrollbarMetrics = provideScrollbarMetrics(), + metrics: ScrollbarMetrics = ScrollbarMetrics.macOs(), trackClickBehavior: TrackClickBehavior = TrackClickBehavior.NextPage, scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.WhenScrolling.defaults(), ): ScrollbarStyle = @@ -40,9 +54,9 @@ public fun ScrollbarStyle.Companion.macOsDark( scrollbarVisibility = scrollbarVisibility, ) -public fun ScrollbarStyle.Companion.winOsDark( - colors: ScrollbarColors = ScrollbarColors.winOsDark(), - metrics: ScrollbarMetrics = provideScrollbarMetrics(), +public fun ScrollbarStyle.Companion.windowsAndLinuxDark( + colors: ScrollbarColors = ScrollbarColors.windowsAndLinuxDark(), + metrics: ScrollbarMetrics = ScrollbarMetrics.windows(), trackClickBehavior: TrackClickBehavior = TrackClickBehavior.JumpToSpot, scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.AlwaysVisible, ): ScrollbarStyle = @@ -53,9 +67,9 @@ public fun ScrollbarStyle.Companion.winOsDark( scrollbarVisibility = scrollbarVisibility, ) -public fun ScrollbarStyle.Companion.winOsLight( - colors: ScrollbarColors = ScrollbarColors.winOsLight(), - metrics: ScrollbarMetrics = provideScrollbarMetrics(), +public fun ScrollbarStyle.Companion.windowsAndLinuxLight( + colors: ScrollbarColors = ScrollbarColors.windowsAndLinuxLight(), + metrics: ScrollbarMetrics = ScrollbarMetrics.windows(), trackClickBehavior: TrackClickBehavior = TrackClickBehavior.JumpToSpot, scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.AlwaysVisible, ): ScrollbarStyle = @@ -66,20 +80,6 @@ public fun ScrollbarStyle.Companion.winOsLight( scrollbarVisibility = scrollbarVisibility, ) -public fun ScrollbarStyle.Companion.dark(): ScrollbarStyle = - if (hostOs.isMacOS) { - ScrollbarStyle.macOsDark() - } else { - ScrollbarStyle.winOsDark() - } - -public fun ScrollbarStyle.Companion.light(): ScrollbarStyle = - if (hostOs.isMacOS) { - ScrollbarStyle.macOsLight() - } else { - ScrollbarStyle.winOsLight() - } - public fun ScrollbarVisibility.WhenScrolling.Companion.defaults( appearAnimationDuration: Duration = 125.milliseconds, disappearAnimationDuration: Duration = 125.milliseconds, @@ -114,7 +114,7 @@ public fun ScrollbarColors.Companion.macOsLight( trackBackgroundHovered, ) -public fun ScrollbarColors.Companion.winOsLight( +public fun ScrollbarColors.Companion.windowsAndLinuxLight( thumbBackground: Color = Color(0x33737373), thumbBackgroundHovered: Color = Color(0x47737373), thumbBackgroundPressed: Color = thumbBackgroundHovered, @@ -156,7 +156,7 @@ public fun ScrollbarColors.Companion.macOsDark( trackBackgroundHovered, ) -public fun ScrollbarColors.Companion.winOsDark( +public fun ScrollbarColors.Companion.windowsAndLinuxDark( thumbBackground: Color = Color(0x47A6A6A6), thumbBackgroundHovered: Color = Color(0x59A6A6A6), thumbBackgroundPressed: Color = Color(0x59A6A6A6), @@ -194,13 +194,6 @@ public fun ScrollbarMetrics.Companion.defaults( trackPaddingExpanded, ) -private fun provideScrollbarMetrics(): ScrollbarMetrics = - when { - hostOs.isMacOS -> ScrollbarMetrics.macOs() - hostOs.isLinux -> ScrollbarMetrics.linux() - else -> ScrollbarMetrics.windows() - } - public fun ScrollbarMetrics.Companion.macOs( thumbCornerSize: CornerSize = CornerSize(100), thumbThickness: Dp = 8.dp, @@ -251,3 +244,103 @@ public fun ScrollbarMetrics.Companion.linux( trackPadding, trackPaddingExpanded, ) + +public fun ScrollbarStyle.Companion.tabStripMacOsDark( + colors: ScrollbarColors = ScrollbarColors.macOsDark(), + metrics: ScrollbarMetrics = ScrollbarMetrics.tabStripMacOs(), + trackClickBehavior: TrackClickBehavior = TrackClickBehavior.NextPage, + scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.WhenScrolling.defaults(), +): ScrollbarStyle = + ScrollbarStyle( + colors = colors, + metrics = metrics, + trackClickBehavior = trackClickBehavior, + scrollbarVisibility = scrollbarVisibility, + ) + +public fun ScrollbarStyle.Companion.tabStripMacOsLight( + colors: ScrollbarColors = ScrollbarColors.macOsLight(), + metrics: ScrollbarMetrics = ScrollbarMetrics.tabStripMacOs(), + trackClickBehavior: TrackClickBehavior = TrackClickBehavior.NextPage, + scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.WhenScrolling.defaults(), +): ScrollbarStyle = + ScrollbarStyle( + colors = colors, + metrics = metrics, + trackClickBehavior = trackClickBehavior, + scrollbarVisibility = scrollbarVisibility, + ) + +public fun ScrollbarStyle.Companion.tabStripWindowsAndLinuxDark( + colors: ScrollbarColors = ScrollbarColors.windowsAndLinuxDark(), + metrics: ScrollbarMetrics = ScrollbarMetrics.tabStripWindowsAndLinux(), + trackClickBehavior: TrackClickBehavior = TrackClickBehavior.JumpToSpot, + scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.AlwaysVisible, +): ScrollbarStyle = + ScrollbarStyle( + colors = colors, + metrics = metrics, + trackClickBehavior = trackClickBehavior, + scrollbarVisibility = scrollbarVisibility, + ) + +public fun ScrollbarStyle.Companion.tabStripWindowsAndLinuxLight( + colors: ScrollbarColors = ScrollbarColors.windowsAndLinuxLight(), + metrics: ScrollbarMetrics = ScrollbarMetrics.tabStripWindowsAndLinux(), + trackClickBehavior: TrackClickBehavior = TrackClickBehavior.JumpToSpot, + scrollbarVisibility: ScrollbarVisibility = ScrollbarVisibility.AlwaysVisible, +): ScrollbarStyle = + ScrollbarStyle( + colors = colors, + metrics = metrics, + trackClickBehavior = trackClickBehavior, + scrollbarVisibility = scrollbarVisibility, + ) + +public fun ScrollbarStyle.Companion.tabStripDark(): ScrollbarStyle = + if (hostOs.isMacOS) { + ScrollbarStyle.tabStripMacOsDark() + } else { + ScrollbarStyle.tabStripWindowsAndLinuxDark() + } + +public fun ScrollbarStyle.Companion.tabStripLight(): ScrollbarStyle = + if (hostOs.isMacOS) { + ScrollbarStyle.tabStripMacOsLight() + } else { + ScrollbarStyle.tabStripWindowsAndLinuxLight() + } + +public fun ScrollbarMetrics.Companion.tabStripMacOs( + thumbCornerSize: CornerSize = CornerSize(100), + thumbThickness: Dp = 3.dp, + minThumbLength: Dp = 20.dp, + trackPadding: PaddingValues = PaddingValues(), + thumbThicknessExpanded: Dp = 3.dp, + trackPaddingExpanded: PaddingValues = PaddingValues(), +): ScrollbarMetrics = + ScrollbarMetrics( + thumbCornerSize, + thumbThickness, + thumbThicknessExpanded, + minThumbLength, + trackPadding, + trackPaddingExpanded, + ) + +public fun ScrollbarMetrics.Companion.tabStripWindowsAndLinux( + thumbCornerSize: CornerSize = CornerSize(0), + thumbThickness: Dp = 3.dp, + minThumbLength: Dp = 16.dp, + trackPadding: PaddingValues = PaddingValues(), + thumbThicknessExpanded: Dp = 3.dp, + trackPaddingExpanded: PaddingValues = PaddingValues(), +): ScrollbarMetrics = + ScrollbarMetrics( + thumbCornerSize, + thumbThickness, + thumbThicknessExpanded, + minThumbLength, + trackPadding, + trackPaddingExpanded, + ) diff --git a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt index 8cdfa108b..7ccfbc8a8 100644 --- a/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt +++ b/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiTabStyling.kt @@ -20,13 +20,12 @@ public val TabStyle.Companion.Default: IntUiDefaultTabStyleFactory get() = IntUiDefaultTabStyleFactory public object IntUiDefaultTabStyleFactory { - @Composable public fun light( colors: TabColors = TabColors.Default.light(), metrics: TabMetrics = TabMetrics.defaults(), icons: TabIcons = TabIcons.defaults(), contentAlpha: TabContentAlpha = TabContentAlpha.default(), - scrollbarStyle: ScrollbarStyle = ScrollbarStyle.macOsLight(), + scrollbarStyle: ScrollbarStyle = ScrollbarStyle.tabStripLight(), ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) @Composable @@ -35,7 +34,7 @@ public object IntUiDefaultTabStyleFactory { metrics: TabMetrics = TabMetrics.defaults(), icons: TabIcons = TabIcons.defaults(), contentAlpha: TabContentAlpha = TabContentAlpha.default(), - scrollbarStyle: ScrollbarStyle = ScrollbarStyle.dark(), + scrollbarStyle: ScrollbarStyle = ScrollbarStyle.tabStripDark(), ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) } @@ -49,7 +48,7 @@ public object IntUiEditorTabStyleFactory { metrics: TabMetrics = TabMetrics.defaults(), icons: TabIcons = TabIcons.defaults(), contentAlpha: TabContentAlpha = TabContentAlpha.editor(), - scrollbarStyle: ScrollbarStyle = ScrollbarStyle.light(), + scrollbarStyle: ScrollbarStyle = ScrollbarStyle.tabStripLight(), ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) @Composable @@ -58,7 +57,7 @@ public object IntUiEditorTabStyleFactory { metrics: TabMetrics = TabMetrics.defaults(), icons: TabIcons = TabIcons.defaults(), contentAlpha: TabContentAlpha = TabContentAlpha.editor(), - scrollbarStyle: ScrollbarStyle = ScrollbarStyle.dark(), + scrollbarStyle: ScrollbarStyle = ScrollbarStyle.tabStripDark(), ): TabStyle = TabStyle(colors, metrics, icons, contentAlpha, scrollbarStyle) } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt index 03a9489f6..84bd518ee 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ComponentShowcaseTab.kt @@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -143,10 +144,9 @@ private fun RowScope.ColumnOne() { } } - var textFieldValue by remember { mutableStateOf("") } + val state = rememberTextFieldState("") TextField( - value = textFieldValue, - onValueChange = { textFieldValue = it }, + state = state, modifier = Modifier.width(200.dp), placeholder = { Text("Write something...") }, ) diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt index 4f2ade916..4cba92bca 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/JewelDemoToolWindowFactory.kt @@ -38,6 +38,10 @@ internal class JewelDemoToolWindowFactory : ToolWindowFactory, DumbAware { } toolWindow.addSwingTab(SwingComparisonTabPanel(), "Swing Comparison") + + toolWindow.addComposeTab("Scrollbars Sample") { + ScrollbarsShowcaseTab() + } } private fun ToolWindow.addSwingTab( diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ScrollbarsShowcaseTab.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ScrollbarsShowcaseTab.kt new file mode 100644 index 000000000..ed12972c4 --- /dev/null +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/ScrollbarsShowcaseTab.kt @@ -0,0 +1,117 @@ +package org.jetbrains.jewel.samples.ideplugin + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +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.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.text.input.rememberTextFieldState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.intellij.ui.JBColor +import org.jetbrains.jewel.bridge.LocalComponent +import org.jetbrains.jewel.bridge.toComposeColor +import org.jetbrains.jewel.foundation.modifier.trackActivation +import org.jetbrains.jewel.foundation.modifier.trackComponentActivation +import org.jetbrains.jewel.foundation.theme.JewelTheme +import org.jetbrains.jewel.ui.Orientation +import org.jetbrains.jewel.ui.component.Divider +import org.jetbrains.jewel.ui.component.Text +import org.jetbrains.jewel.ui.component.TextArea +import org.jetbrains.jewel.ui.component.VerticalScrollbar +import org.jetbrains.jewel.ui.theme.scrollbarStyle +import java.util.Locale + +@Composable +internal fun ScrollbarsShowcaseTab() { + val bgColor by remember(JBColor.PanelBackground.rgb) { mutableStateOf(JBColor.PanelBackground.toComposeColor()) } + + Column( + Modifier + .trackComponentActivation(LocalComponent.current) + .fillMaxSize() + .background(bgColor) + .padding(16.dp) + .trackActivation(), + verticalArrangement = Arrangement.spacedBy(16.dp), + ) { + Row(modifier = Modifier.fillMaxWidth().height(200.dp)) { + val textFieldState = rememberTextFieldState(ANDROID_IPSUM) + TextArea( + state = textFieldState, + modifier = Modifier.size(300.dp), + ) + + Divider(Orientation.Vertical, modifier = Modifier.width(10.dp)) + + Box(Modifier.border(1.dp, JewelTheme.globalColors.borders.normal)) { + val scrollState = rememberLazyListState() + LazyColumn( + Modifier + .width(200.dp) + .padding(end = JewelTheme.scrollbarStyle.metrics.thumbThicknessExpanded) + .align(Alignment.CenterStart), + verticalArrangement = Arrangement.spacedBy(4.dp), + state = scrollState, + ) { + items(LIST_ITEMS) { item -> + Column(modifier = Modifier.height(48.dp)) { + Text( + modifier = Modifier.padding(horizontal = 8.dp), + text = item, + ) + Divider(orientation = Orientation.Horizontal, color = Color.Gray) + } + } + } + VerticalScrollbar( + scrollState = scrollState, + modifier = Modifier.align(Alignment.CenterEnd), + ) + } + } + } +} + +private const val ANDROID_IPSUM = + "Jetpack Compose dolor sit amet, viewBinding consectetur adipiscing elit, sed do eiusmod tempor incididunt" + + " ut unitTest et dolore magna aliqua. Dependency injection enim ad minim veniam, quis nostrud Dagger-Hilt " + + "ullamco laboris nisi ut aliquip ex ea Lottie animation consequat. Retrofit irure dolor in reprehenderit in" + + " AndroidX velit esse cillum dolore eu fugiat nulla pariatur. Gradle sync dolor sit amet, compileSdkVersion" + + " consectetur adipiscing elit, sed do eiusmod minimSdkVersion tempor incididunt ut labore et dolore magna" + + " aliqua. Ut enim ad activity_main.xml veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip" + + " ex ea compileOptions consequat. Duis aute irure dolor in reprehenderit in logcat velit esse cillum dolore" + + "eu fugiat nulla pariatur. Excepteur sint occaecat proident, sunt in culpa qui officia debugImplementation" + + " deserunt mollit anim id est laborum. Manifest merger dolor sit amet, androidx.appcompat.app.AppCompatActivity" + + " adipiscing elit, sed do eiusmod tempor incididunt ut buildToolsVersion et dolore magna aliqua. Proguard" + + " rules enim ad minim veniam, quis nostrud fragmentContainerView ullamco laboris nisi ut aliquip ex ea" + + " dataBinding compilerOptions consequat. Kotlin coroutine aute irure dolor in reprehenderit in ViewModel" + + " velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat Room database non proident," + + " sunt in culpa qui officia material design deserunt mollit anim id est laborum." + +private val LIST_ITEMS = + ANDROID_IPSUM + .split(",") + .map { lorem -> + lorem + .trim() + .replaceFirstChar { + if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() + } + } diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt index 4ecd4b43d..405bfa2c5 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/SwingComparisonTabPanel.kt @@ -7,11 +7,9 @@ import androidx.compose.foundation.layout.calculateEndPadding import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity @@ -123,8 +121,8 @@ internal class SwingComparisonTabPanel : BorderLayoutPanel() { textField().align(AlignY.CENTER) compose { - var text by remember { mutableStateOf("") } - TextField(text, { text = it }) + val state = rememberTextFieldState("") + TextField(state) } }.layout(RowLayout.PARENT_GRID) } @@ -134,7 +132,6 @@ internal class SwingComparisonTabPanel : BorderLayoutPanel() { textArea().align(AlignY.CENTER).applyToComponent { rows = 3 } compose { - var text by remember { mutableStateOf("") } val metrics = remember(JBFont.label(), LocalDensity.current) { getFontMetrics(JBFont.label()) } val charWidth = remember(metrics.widths) { @@ -147,13 +144,14 @@ internal class SwingComparisonTabPanel : BorderLayoutPanel() { val height = remember(lineHeight) { (3 * lineHeight) } val contentPadding = JewelTheme.textAreaStyle.metrics.contentPadding + val state = rememberTextFieldState("Hello") TextArea( - text, - { text = it }, - Modifier.size( - width = width.dp + contentPadding.horizontal(LocalLayoutDirection.current), - height = height.dp + contentPadding.vertical(), - ), + state = state, + modifier = + Modifier.size( + width = width.dp + contentPadding.horizontal(LocalLayoutDirection.current), + height = height.dp + contentPadding.vertical(), + ), ) } }.layout(RowLayout.PARENT_GRID) diff --git a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt index fdb571db8..f47087c57 100644 --- a/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt +++ b/samples/ide-plugin/src/main/kotlin/org/jetbrains/jewel/samples/ideplugin/releasessample/ReleasesSampleCompose.kt @@ -33,6 +33,7 @@ import androidx.compose.foundation.onClick import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollbarAdapter import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -42,6 +43,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -277,9 +279,13 @@ private fun SearchBar( focusRequester.requestFocus() } + val state = rememberTextFieldState(filterText) + LaunchedEffect(state) { + snapshotFlow { state.text } + .collect { service.filterContent(it.toString()) } + } TextField( - value = filterText, - onValueChange = { service.filterContent(it) }, + state = state, modifier = modifier.focusRequester(focusRequester), leadingIcon = { Icon(AllIconsKeys.Actions.Find, contentDescription = null, Modifier.padding(end = 8.dp)) diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Scrollbars.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Scrollbars.kt index e90a177e1..be6663483 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Scrollbars.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Scrollbars.kt @@ -29,8 +29,8 @@ import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.intui.standalone.styling.defaults import org.jetbrains.jewel.intui.standalone.styling.macOsDark import org.jetbrains.jewel.intui.standalone.styling.macOsLight -import org.jetbrains.jewel.intui.standalone.styling.winOsDark -import org.jetbrains.jewel.intui.standalone.styling.winOsLight +import org.jetbrains.jewel.intui.standalone.styling.windowsAndLinuxDark +import org.jetbrains.jewel.intui.standalone.styling.windowsAndLinuxLight import org.jetbrains.jewel.ui.Orientation import org.jetbrains.jewel.ui.component.CheckboxRow import org.jetbrains.jewel.ui.component.Divider @@ -152,13 +152,13 @@ fun readStyle( if (isMac) { ScrollbarStyle.macOsDark() } else { - ScrollbarStyle.winOsDark() + ScrollbarStyle.windowsAndLinuxDark() } } else { if (isMac) { ScrollbarStyle.macOsLight() } else { - ScrollbarStyle.winOsLight() + ScrollbarStyle.windowsAndLinuxLight() } } 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 ee8631b59..3930fa2ed 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 @@ -5,11 +5,8 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -34,29 +31,30 @@ private const val LOREM_IPSUM = @Composable fun TextAreas() { Row( - Modifier.padding(horizontal = 16.dp).height(150.dp), + Modifier.padding(horizontal = 16.dp).height(200.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.Top, ) { - var text1 by remember { mutableStateOf(LOREM_IPSUM) } - TextArea(text1, { text1 = it }, modifier = Modifier.weight(1f).fillMaxHeight()) + TextArea( + state = rememberTextFieldState(LOREM_IPSUM), + modifier = Modifier.weight(1f).fillMaxHeight(), + ) - var text2 by remember { mutableStateOf(LOREM_IPSUM) } - TextArea(text2, { text2 = it }, modifier = Modifier.weight(1f).fillMaxHeight(), enabled = false) + TextArea( + state = rememberTextFieldState(LOREM_IPSUM), + modifier = Modifier.weight(1f).fillMaxHeight(), + enabled = false, + ) - var text3 by remember { mutableStateOf("") } TextArea( - text3, - { text3 = it }, + state = rememberTextFieldState(""), modifier = Modifier.weight(1f).fillMaxHeight(), outline = Outline.Error, placeholder = { Text("Text area with error") }, ) - var text4 by remember { mutableStateOf("") } TextArea( - text4, - { text4 = it }, + state = rememberTextFieldState(""), modifier = Modifier.weight(1f).fillMaxHeight(), outline = Outline.Warning, placeholder = { Text("Text area with warning") }, 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 640ef4ca5..b4bd56e85 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 @@ -9,11 +9,11 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.input.rememberTextFieldState +import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -42,33 +42,57 @@ fun TextFields() { horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically, ) { - var text1 by remember { mutableStateOf("TextField") } - TextField(text1, { text1 = it }) + val state1 = rememberTextFieldState("TextField") + TextField( + state = state1, + modifier = Modifier.width(200.dp), + ) - var text2 by remember { mutableStateOf("") } - TextField(text2, { text2 = it }, placeholder = { Text("Placeholder") }) + val state2 = rememberTextFieldState("") + TextField( + state = state2, + placeholder = { Text("Placeholder") }, + modifier = Modifier.width(200.dp), + ) - var text3 by remember { mutableStateOf("") } - TextField(text3, { text3 = it }, outline = Outline.Error, placeholder = { Text("Error outline") }) + val state3 = rememberTextFieldState("") + TextField( + state = state3, + outline = Outline.Error, + placeholder = { Text("Error outline") }, + modifier = Modifier.width(200.dp), + ) + } - var text4 by remember { mutableStateOf("") } - TextField(text4, { text4 = it }, outline = Outline.Warning, placeholder = { Text("Warning outline") }) + 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), + ) - var text5 by remember { mutableStateOf("Disabled") } - TextField(text5, { text5 = it }, enabled = false) + val state2 = rememberTextFieldState("Disabled") + TextField( + state = state2, + enabled = false, + modifier = Modifier.width(200.dp), + ) } Row( horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.Top, ) { - var text1 by remember { mutableStateOf("") } + val state1 = rememberTextFieldState("") TextField( - value = text1, - onValueChange = { text1 = it }, - placeholder = { - Text("With leading icon") - }, + state = state1, + placeholder = { Text("With leading icon") }, + modifier = Modifier.width(200.dp), leadingIcon = { Icon( key = AllIconsKeys.Actions.Find, @@ -79,15 +103,16 @@ fun TextFields() { }, ) - var text2 by remember { mutableStateOf("") } + val state2 = rememberTextFieldState("") TextField( - value = text2, - onValueChange = { text2 = it }, - placeholder = { - Text("With trailing button") - }, + state = state2, + placeholder = { Text("With trailing button") }, + modifier = Modifier.width(200.dp), trailingIcon = { - CloseIconButton(text2.isNotEmpty()) { text2 = "" } + CloseIconButton( + isVisible = state2.text.isNotEmpty(), + onClick = { state2.setTextAndPlaceCursorAtEnd("") }, + ) }, ) } diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownEditor.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownEditor.kt index 08b3cd56b..1bad3c9bb 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownEditor.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/markdown/MarkdownEditor.kt @@ -11,11 +11,14 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -130,10 +133,15 @@ private fun Editor( onMarkdownChange: (String) -> Unit, modifier: Modifier = Modifier, ) { + val state = rememberTextFieldState(currentMarkdown) + LaunchedEffect(state) { + snapshotFlow { state.text } + .collect { onMarkdownChange(it.toString()) } + } + Box(modifier.padding(16.dp)) { TextArea( - value = currentMarkdown, - onValueChange = onMarkdownChange, + state = state, modifier = Modifier.align(Alignment.TopStart).fillMaxWidth(), undecorated = true, textStyle = JewelTheme.editorTextStyle, diff --git a/ui/api/ui.api b/ui/api/ui.api index 7ea1c929b..a89113e69 100644 --- a/ui/api/ui.api +++ b/ui/api/ui.api @@ -870,11 +870,13 @@ public final class org/jetbrains/jewel/ui/component/TabsKt { } public final class org/jetbrains/jewel/ui/component/TextAreaKt { + public static final fun TextArea (Landroidx/compose/foundation/text/input/TextFieldState;Landroidx/compose/ui/Modifier;ZZLorg/jetbrains/jewel/ui/Outline;Lkotlin/jvm/functions/Function2;ZLandroidx/compose/foundation/text/KeyboardOptions;ILorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/foundation/interaction/MutableInteractionSource;ZLandroidx/compose/runtime/Composer;III)V public static final fun TextArea (Landroidx/compose/ui/text/input/TextFieldValue;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;ZZLkotlin/jvm/functions/Function2;ZLorg/jetbrains/jewel/ui/Outline;Landroidx/compose/ui/text/input/VisualTransformation;Landroidx/compose/foundation/text/KeyboardOptions;Landroidx/compose/foundation/text/KeyboardActions;ILkotlin/jvm/functions/Function1;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;III)V public static final fun TextArea (Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;ZZLorg/jetbrains/jewel/ui/Outline;Lkotlin/jvm/functions/Function2;ZLandroidx/compose/ui/text/input/VisualTransformation;Landroidx/compose/foundation/text/KeyboardOptions;Landroidx/compose/foundation/text/KeyboardActions;ILkotlin/jvm/functions/Function1;Lorg/jetbrains/jewel/ui/component/styling/TextAreaStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;III)V } public final class org/jetbrains/jewel/ui/component/TextFieldKt { + public static final fun TextField (Landroidx/compose/foundation/text/input/TextFieldState;Landroidx/compose/ui/Modifier;ZZLorg/jetbrains/jewel/ui/Outline;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ZLandroidx/compose/foundation/text/KeyboardOptions;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;III)V public static final fun TextField (Landroidx/compose/ui/text/input/TextFieldValue;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;ZZLorg/jetbrains/jewel/ui/Outline;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ZLandroidx/compose/ui/text/input/VisualTransformation;Landroidx/compose/foundation/text/KeyboardOptions;Landroidx/compose/foundation/text/KeyboardActions;Lkotlin/jvm/functions/Function1;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Landroidx/compose/ui/text/TextStyle;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;III)V public static final fun TextField (Ljava/lang/String;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;ZZLorg/jetbrains/jewel/ui/Outline;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;ZLandroidx/compose/ui/text/input/VisualTransformation;Landroidx/compose/foundation/text/KeyboardOptions;Landroidx/compose/foundation/text/KeyboardActions;Lkotlin/jvm/functions/Function1;Lorg/jetbrains/jewel/ui/component/styling/TextFieldStyle;Landroidx/compose/foundation/interaction/MutableInteractionSource;Landroidx/compose/runtime/Composer;III)V } diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt index a61cb7db8..afb7a873c 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/InputField.kt @@ -3,17 +3,26 @@ package org.jetbrains.jewel.ui.component import androidx.compose.foundation.background import androidx.compose.foundation.interaction.FocusInteraction import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldLineLimits.MultiLine +import androidx.compose.foundation.text.input.TextFieldLineLimits.SingleLine +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.isSpecified @@ -21,6 +30,7 @@ import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.Stroke import org.jetbrains.jewel.foundation.modifier.border import org.jetbrains.jewel.foundation.state.CommonStateBitMask.Active @@ -35,14 +45,117 @@ import org.jetbrains.jewel.ui.focusOutline import org.jetbrains.jewel.ui.outline import org.jetbrains.jewel.ui.util.thenIf +@Composable +internal fun InputField( + state: TextFieldState, + enabled: Boolean, + readOnly: Boolean, + outline: Outline, + undecorated: Boolean, + keyboardOptions: KeyboardOptions, + singleLine: Boolean, + maxLines: Int, + interactionSource: MutableInteractionSource, + style: InputFieldStyle, + textStyle: TextStyle, + showScrollbar: Boolean, + modifier: Modifier, + decorationBox: @Composable (innerTextField: @Composable () -> Unit, state: InputFieldState) -> Unit, +) { + var inputState by remember(interactionSource) { + mutableStateOf(InputFieldState.of(enabled = enabled)) + } + remember(enabled) { inputState = inputState.copy(enabled = enabled) } + + LaunchedEffect(interactionSource) { + interactionSource.interactions.collect { interaction -> + when (interaction) { + is FocusInteraction.Focus -> inputState = inputState.copy(focused = true) + is FocusInteraction.Unfocus -> inputState = inputState.copy(focused = false) + } + } + } + + val colors = style.colors + val backgroundColor by colors.backgroundFor(inputState) + val shape = RoundedCornerShape(style.metrics.cornerSize) + + val backgroundModifier = + Modifier.thenIf(!undecorated && backgroundColor.isSpecified) { + background(backgroundColor, shape) + } + + val borderColor by style.colors.borderFor(inputState) + val hasNoOutline = outline == Outline.None + val borderModifier = + Modifier.thenIf(!undecorated && borderColor.isSpecified && hasNoOutline) { + border( + alignment = Stroke.Alignment.Center, + width = style.metrics.borderWidth, + color = borderColor, + shape = shape, + ) + } + + val contentColor by colors.contentFor(inputState) + val mergedTextStyle = textStyle.copy(color = contentColor) + val caretColor by colors.caretFor(inputState) + + val lineLimits = + when { + singleLine -> SingleLine + else -> MultiLine(maxLines) + } + + val scrollState = rememberScrollState() + val canScroll by remember { + derivedStateOf { + scrollState.canScrollBackward || scrollState.canScrollForward + } + } + + Box( + modifier = modifier + .then(backgroundModifier) + .then(borderModifier) + .thenIf(!undecorated && hasNoOutline) { focusOutline(inputState, shape) } + .outline(inputState, outline, shape, Stroke.Alignment.Center), + ) { + BasicTextField( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.CenterStart) + .thenIf(canScroll && showScrollbar) { padding(end = 12.dp) }, + state = state, + enabled = enabled, + readOnly = readOnly, + textStyle = mergedTextStyle, + cursorBrush = SolidColor(caretColor), + keyboardOptions = keyboardOptions, + lineLimits = lineLimits, + interactionSource = interactionSource, + decorator = { innerTextField: @Composable () -> Unit -> decorationBox(innerTextField, inputState) }, + scrollState = scrollState, + ) + + if (showScrollbar) { + VerticalScrollbar( + scrollState = scrollState, + modifier = Modifier.align(Alignment.CenterEnd), + interactionSource = interactionSource, + ) + } + } +} + +@Deprecated("Please use InputField(state) instead. If you want to observe text changes, use snapshotFlow { state.text }") @Composable internal fun InputField( value: TextFieldValue, onValueChange: (TextFieldValue) -> Unit, - modifier: Modifier, enabled: Boolean, - readOnly: Boolean, outline: Outline, + readOnly: Boolean, undecorated: Boolean, visualTransformation: VisualTransformation, keyboardOptions: KeyboardOptions, @@ -53,6 +166,7 @@ internal fun InputField( interactionSource: MutableInteractionSource, style: InputFieldStyle, textStyle: TextStyle, + modifier: Modifier, decorationBox: @Composable (innerTextField: @Composable () -> Unit, state: InputFieldState) -> Unit, ) { var inputState by remember(interactionSource) { mutableStateOf(InputFieldState.of(enabled = enabled)) } diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Scrollbars.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Scrollbars.kt index eead891dd..92998d211 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Scrollbars.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Scrollbars.kt @@ -337,21 +337,20 @@ private fun ScrollbarImpl( } } - val thumbBackgroundColor = if (isHighlighted) { - style.colors.thumbBackground - } else { + val targetColor = if (isHighlighted) { style.colors.thumbBackgroundHovered + } else { + style.colors.thumbBackground } val thumbColor = if (style.scrollbarVisibility is WhenScrolling) { val durationMillis = style.scrollbarVisibility.expandAnimationDuration.inWholeMilliseconds.toInt() animateColorAsState( - targetValue = thumbBackgroundColor, + targetValue = targetColor, animationSpec = tween(durationMillis), ).value } else { - thumbBackgroundColor + targetColor } - val isVisible = sliderAdapter.thumbSize < containerSize Layout( diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt index 54c045901..ec4038ae7 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TabStrip.kt @@ -50,19 +50,19 @@ public fun TabStrip( ) { Row( modifier = - Modifier - .horizontalScroll(scrollState) - .scrollable( - orientation = Orientation.Vertical, - reverseDirection = - ScrollableDefaults.reverseDirection( - LocalLayoutDirection.current, - Orientation.Vertical, - false, - ), - state = scrollState, - interactionSource = remember { MutableInteractionSource() }, - ).selectableGroup(), + Modifier + .horizontalScroll(scrollState) + .scrollable( + orientation = Orientation.Vertical, + reverseDirection = + ScrollableDefaults.reverseDirection( + LocalLayoutDirection.current, + Orientation.Vertical, + false, + ), + state = scrollState, + interactionSource = remember { MutableInteractionSource() }, + ).selectableGroup(), ) { tabs.forEach { TabImpl(isActive = tabStripState.isActive, tabData = it) } } @@ -72,7 +72,7 @@ public fun TabStrip( enter = fadeIn(tween(durationMillis = 125, delayMillis = 0, easing = LinearEasing)), exit = fadeOut(tween(durationMillis = 125, delayMillis = 700, easing = LinearEasing)), ) { - TabStripHorizontalScrollbar( + HorizontalScrollbar( adapter = rememberScrollbarAdapter(scrollState), style = style.scrollbarStyle, modifier = Modifier.fillMaxWidth(), diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextArea.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextArea.kt index fee1c2d7e..cbdcb4cab 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextArea.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextArea.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue @@ -37,6 +38,54 @@ import org.jetbrains.jewel.ui.theme.textAreaStyle * component when the [value] is empty. */ @Composable +public fun TextArea( + state: TextFieldState, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + outline: Outline = Outline.None, + placeholder: @Composable() (() -> Unit)? = null, + undecorated: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + maxLines: Int = Int.MAX_VALUE, + style: TextAreaStyle = JewelTheme.textAreaStyle, + textStyle: TextStyle = JewelTheme.defaultTextStyle, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + showScrollbar: Boolean = true, +) { + val minSize = style.metrics.minSize + InputField( + state = state, + enabled = enabled, + readOnly = readOnly, + outline = outline, + undecorated = undecorated, + keyboardOptions = keyboardOptions, + singleLine = false, + maxLines = maxLines, + interactionSource = interactionSource, + style = style, + textStyle = textStyle, + showScrollbar = showScrollbar, + modifier = modifier.defaultMinSize(minWidth = minSize.width, minHeight = minSize.height), + decorationBox = { innerTextField, _ -> + TextAreaDecorationBox( + innerTextField = innerTextField, + contentPadding = style.metrics.contentPadding, + placeholderTextColor = style.colors.placeholder, + placeholder = if (state.text.isEmpty()) placeholder else null, + textStyle = textStyle, + ) + }, + ) +} + +/** + * @param placeholder the optional placeholder to be displayed over the + * component when the [value] is empty. + */ +@Deprecated("Please use TextArea(state) instead. If you want to observe text changes, use snapshotFlow { state.text }") +@Composable public fun TextArea( value: String, onValueChange: (String) -> Unit, @@ -92,6 +141,7 @@ public fun TextArea( * @param placeholder the optional placeholder to be displayed over the * component when the [value] is empty. */ +@Deprecated("Please use TextArea(state) instead. If you want to observe text changes, use snapshotFlow { state.text }") @Composable public fun TextArea( value: TextFieldValue, @@ -185,13 +235,15 @@ private fun TextAreaDecorationBox( .copy(minHeight = 0) val textAreaPlaceable = - measurables.single { it.layoutId == TEXT_AREA_ID } + measurables + .single { it.layoutId == TEXT_AREA_ID } .measure(textAreaConstraints) // Measure placeholder val placeholderConstraints = textAreaConstraints.copy(minWidth = 0, minHeight = 0) val placeholderPlaceable = - measurables.find { it.layoutId == PLACEHOLDER_ID } + measurables + .find { it.layoutId == PLACEHOLDER_ID } ?.measure(placeholderConstraints) val width = calculateWidth(textAreaPlaceable, placeholderPlaceable, incomingConstraints) diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextField.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextField.kt index 553b89622..abd4722a2 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextField.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/TextField.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.text.input.TextFieldState import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue @@ -37,6 +38,59 @@ import kotlin.math.max * component when the [value] is empty. */ @Composable +public fun TextField( + state: TextFieldState, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + outline: Outline = Outline.None, + placeholder: @Composable() (() -> Unit)? = null, + leadingIcon: @Composable() (() -> Unit)? = null, + trailingIcon: @Composable() (() -> Unit)? = null, + undecorated: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + style: TextFieldStyle = JewelTheme.textFieldStyle, + textStyle: TextStyle = JewelTheme.defaultTextStyle, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + InputField( + state = state, + enabled = enabled, + readOnly = readOnly, + outline = outline, + undecorated = undecorated, + keyboardOptions = keyboardOptions, + singleLine = true, + maxLines = 1, + interactionSource = interactionSource, + style = style, + textStyle = textStyle, + showScrollbar = false, + modifier = modifier, + decorationBox = { innerTextField, _ -> + val minSize = style.metrics.minSize + + TextFieldDecorationBox( + modifier = Modifier + .defaultMinSize(minWidth = minSize.width, minHeight = minSize.height) + .padding(style.metrics.contentPadding), + innerTextField = innerTextField, + textStyle = textStyle, + placeholderTextColor = style.colors.placeholder, + placeholder = if (state.text.isEmpty()) placeholder else null, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + ) + }, + ) +} + +/** + * @param placeholder the optional placeholder to be displayed over the + * component when the [value] is empty. + */ +@Deprecated("Please use TextField(state) instead. If you want to observe text changes, use snapshotFlow { state.text }") +@Composable public fun TextField( value: String, onValueChange: (String) -> Unit, @@ -92,6 +146,7 @@ public fun TextField( * @param placeholder the optional placeholder to be displayed over the * component when the [value] is empty. */ +@Deprecated("Please use TextField(state) instead. If you want to observe text changes, use snapshotFlow { state.text }") @Composable public fun TextField( value: TextFieldValue,