diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt index 9f41d0c669c88..97dcae1bbebe6 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt @@ -89,6 +89,8 @@ internal fun createBridgeComponentStyling(theme: ThemeDefinition): ComponentStyl linkStyle = readLinkStyle(), menuStyle = menuStyle, outlinedButtonStyle = readOutlinedButtonStyle(), + defaultSlimButtonStyle = readDefaultSlimButtonStyle(), + outlinedSlimButtonStyle = readOutlinedSlimButtonStyle(), outlinedSplitButtonStyle = readOutlinedSplitButtonStyle(), popupContainerStyle = readPopupContainerStyle(), radioButtonStyle = readRadioButtonStyle(), diff --git a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeButton.kt b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeButton.kt index 698bb58d10d9d..b641a1bfa9755 100644 --- a/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeButton.kt +++ b/platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridgeButton.kt @@ -123,4 +123,28 @@ internal fun readOutlinedButtonStyle(): ButtonStyle { ) } +internal fun readDefaultSlimButtonStyle(): ButtonStyle { + val defaultButtonStyle = readDefaultButtonStyle() + return createSlimButtonStyle(colors = defaultButtonStyle.colors) +} + +internal fun readOutlinedSlimButtonStyle(): ButtonStyle { + val outlinedButtonStyle = readOutlinedButtonStyle() + return createSlimButtonStyle(colors = outlinedButtonStyle.colors) +} + private fun buttonCornerSize(): CornerSize = CornerSize(DarculaUIUtil.BUTTON_ARC.dp.safeValue() / 2) + +private fun createSlimButtonStyle(colors: ButtonColors): ButtonStyle { + return ButtonStyle( + colors = colors, + metrics = ButtonMetrics( + cornerSize = buttonCornerSize(), + padding = PaddingValues(horizontal = 8.dp, vertical = 2.dp), + minSize = DpSize(60.dp, 24.dp), + borderWidth = borderWidth, + focusOutlineExpand = 1.5.dp, + ), + focusOutlineAlignment = Stroke.Alignment.Center, + ) +} diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt index 1ded935d9e331..a3d21753cefeb 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/styling/IntUiButtonStyling.kt @@ -214,3 +214,28 @@ public fun ButtonMetrics.Companion.outlined( borderWidth: Dp = 1.dp, focusOutlineExpand: Dp = Dp.Unspecified, ): ButtonMetrics = ButtonMetrics(cornerSize, padding, minSize, borderWidth, focusOutlineExpand) + +public fun ButtonMetrics.Companion.slim( + cornerSize: CornerSize = CornerSize(4.dp), + padding: PaddingValues = PaddingValues(horizontal = 8.dp, vertical = 2.dp), + minSize: DpSize = DpSize(60.dp, 24.dp), + borderWidth: Dp = 1.dp, + focusOutlineExpand: Dp = 1.5.dp, +): ButtonMetrics = ButtonMetrics(cornerSize, padding, minSize, borderWidth, focusOutlineExpand) + +public val ButtonStyle.Companion.Slim: IntUiSlimButtonStyleFactory + get() = IntUiSlimButtonStyleFactory + +public object IntUiSlimButtonStyleFactory { + public fun light( + colors: ButtonColors = ButtonColors.Default.light(), + metrics: ButtonMetrics = ButtonMetrics.slim(), + focusOutlineAlignment: Stroke.Alignment = Stroke.Alignment.Center, + ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) + + public fun dark( + colors: ButtonColors = ButtonColors.Default.dark(), + metrics: ButtonMetrics = ButtonMetrics.slim(), + focusOutlineAlignment: Stroke.Alignment = Stroke.Alignment.Center, + ): ButtonStyle = ButtonStyle(colors, metrics, focusOutlineAlignment) +} diff --git a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt index 22e0ea17b1711..8232c898148b8 100644 --- a/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt +++ b/platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt @@ -25,6 +25,7 @@ import org.jetbrains.jewel.intui.standalone.menuShortcut.StandaloneShortcutProvi import org.jetbrains.jewel.intui.standalone.styling.Default import org.jetbrains.jewel.intui.standalone.styling.Editor import org.jetbrains.jewel.intui.standalone.styling.Outlined +import org.jetbrains.jewel.intui.standalone.styling.Slim import org.jetbrains.jewel.intui.standalone.styling.Undecorated import org.jetbrains.jewel.intui.standalone.styling.dark import org.jetbrains.jewel.intui.standalone.styling.darkTransparentBackground @@ -35,6 +36,7 @@ import org.jetbrains.jewel.ui.DefaultComponentStyling import org.jetbrains.jewel.ui.LocalMenuItemShortcutHintProvider import org.jetbrains.jewel.ui.LocalMenuItemShortcutProvider import org.jetbrains.jewel.ui.LocalTypography +import org.jetbrains.jewel.ui.component.styling.ButtonColors import org.jetbrains.jewel.ui.component.styling.ButtonStyle import org.jetbrains.jewel.ui.component.styling.CheckboxStyle import org.jetbrains.jewel.ui.component.styling.ChipStyle @@ -263,6 +265,8 @@ public fun ComponentStyling.dark( linkStyle: LinkStyle = LinkStyle.dark(), menuStyle: MenuStyle = MenuStyle.dark(), outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(), + defaultSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.dark(), + outlinedSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.dark(colors = ButtonColors.Outlined.dark()), popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(), outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(), radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(), @@ -300,6 +304,8 @@ public fun ComponentStyling.dark( linkStyle = linkStyle, menuStyle = menuStyle, outlinedButtonStyle = outlinedButtonStyle, + defaultSlimButtonStyle = defaultSlimButtonStyle, + outlinedSlimButtonStyle = outlinedSlimButtonStyle, popupContainerStyle = popupContainerStyle, outlinedSplitButtonStyle = outlinedSplitButtonStyle, radioButtonStyle = radioButtonStyle, @@ -340,6 +346,8 @@ public fun ComponentStyling.dark( linkStyle: LinkStyle = LinkStyle.dark(), menuStyle: MenuStyle = MenuStyle.dark(), outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(), + defaultSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.dark(), + outlinedSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.dark(colors = ButtonColors.Outlined.dark()), popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(), outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(), radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(), @@ -375,6 +383,8 @@ public fun ComponentStyling.dark( linkStyle = linkStyle, menuStyle = menuStyle, outlinedButtonStyle = outlinedButtonStyle, + defaultSlimButtonStyle = defaultSlimButtonStyle, + outlinedSlimButtonStyle = outlinedSlimButtonStyle, popupContainerStyle = popupContainerStyle, outlinedSplitButtonStyle = outlinedSplitButtonStyle, radioButtonStyle = radioButtonStyle, @@ -414,6 +424,8 @@ public fun ComponentStyling.dark( linkStyle: LinkStyle = LinkStyle.dark(), menuStyle: MenuStyle = MenuStyle.dark(), outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(), + defaultSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.dark(), + outlinedSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.dark(colors = ButtonColors.Outlined.dark()), popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(), outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(), radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(), @@ -449,6 +461,8 @@ public fun ComponentStyling.dark( linkStyle = linkStyle, menuStyle = menuStyle, outlinedButtonStyle = outlinedButtonStyle, + defaultSlimButtonStyle = defaultSlimButtonStyle, + outlinedSlimButtonStyle = outlinedSlimButtonStyle, popupContainerStyle = popupContainerStyle, outlinedSplitButtonStyle = outlinedSplitButtonStyle, radioButtonStyle = radioButtonStyle, @@ -489,6 +503,8 @@ public fun ComponentStyling.light( menuStyle: MenuStyle = MenuStyle.light(), popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(), outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(), + defaultSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.light(), + outlinedSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.light(colors = ButtonColors.Outlined.light()), outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(), radioButtonStyle: RadioButtonStyle = RadioButtonStyle.light(), scrollbarStyle: ScrollbarStyle = ScrollbarStyle.light(), @@ -525,6 +541,8 @@ public fun ComponentStyling.light( linkStyle = linkStyle, menuStyle = menuStyle, outlinedButtonStyle = outlinedButtonStyle, + defaultSlimButtonStyle = defaultSlimButtonStyle, + outlinedSlimButtonStyle = outlinedSlimButtonStyle, popupContainerStyle = popupContainerStyle, outlinedSplitButtonStyle = outlinedSplitButtonStyle, radioButtonStyle = radioButtonStyle, @@ -566,6 +584,8 @@ public fun ComponentStyling.light( menuStyle: MenuStyle = MenuStyle.light(), popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(), outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(), + defaultSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.light(), + outlinedSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.light(colors = ButtonColors.Outlined.light()), outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(), radioButtonStyle: RadioButtonStyle = RadioButtonStyle.light(), scrollbarStyle: ScrollbarStyle = ScrollbarStyle.light(), @@ -600,6 +620,8 @@ public fun ComponentStyling.light( linkStyle = linkStyle, menuStyle = menuStyle, outlinedButtonStyle = outlinedButtonStyle, + defaultSlimButtonStyle = defaultSlimButtonStyle, + outlinedSlimButtonStyle = outlinedSlimButtonStyle, popupContainerStyle = popupContainerStyle, outlinedSplitButtonStyle = outlinedSplitButtonStyle, radioButtonStyle = radioButtonStyle, @@ -640,6 +662,8 @@ public fun ComponentStyling.light( menuStyle: MenuStyle = MenuStyle.light(), popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(), outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(), + defaultSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.light(), + outlinedSlimButtonStyle: ButtonStyle = ButtonStyle.Slim.light(colors = ButtonColors.Outlined.light()), outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(), radioButtonStyle: RadioButtonStyle = RadioButtonStyle.light(), scrollbarStyle: ScrollbarStyle = ScrollbarStyle.light(), @@ -674,6 +698,8 @@ public fun ComponentStyling.light( linkStyle = linkStyle, menuStyle = menuStyle, outlinedButtonStyle = outlinedButtonStyle, + defaultSlimButtonStyle = defaultSlimButtonStyle, + outlinedSlimButtonStyle = outlinedSlimButtonStyle, popupContainerStyle = popupContainerStyle, outlinedSplitButtonStyle = outlinedSplitButtonStyle, radioButtonStyle = radioButtonStyle, diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt index a95382e2443d2..111303efdf6af 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/Buttons.kt @@ -28,6 +28,7 @@ import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.foundation.util.JewelLogger import org.jetbrains.jewel.ui.component.ActionButton import org.jetbrains.jewel.ui.component.DefaultButton +import org.jetbrains.jewel.ui.component.DefaultSlimButton import org.jetbrains.jewel.ui.component.DefaultSplitButton import org.jetbrains.jewel.ui.component.GroupHeader import org.jetbrains.jewel.ui.component.Icon @@ -36,6 +37,7 @@ import org.jetbrains.jewel.ui.component.IconButton import org.jetbrains.jewel.ui.component.InfoText import org.jetbrains.jewel.ui.component.MenuScope import org.jetbrains.jewel.ui.component.OutlinedButton +import org.jetbrains.jewel.ui.component.OutlinedSlimButton import org.jetbrains.jewel.ui.component.OutlinedSplitButton import org.jetbrains.jewel.ui.component.SelectableIconActionButton import org.jetbrains.jewel.ui.component.SelectableIconButton @@ -91,6 +93,23 @@ private fun NormalButtons() { DefaultButton(onClick = {}, enabled = false) { SingleLineText("Default disabled") } } + + GroupHeader("Slim buttons") + + FlowRow( + Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + itemVerticalAlignment = Alignment.CenterVertically, + ) { + DefaultSlimButton(onClick = {}) { SingleLineText("Slim Default") } + + DefaultSlimButton(onClick = {}, enabled = false) { SingleLineText("Slim Disabled") } + + OutlinedSlimButton(onClick = {}) { SingleLineText("Outlined Slim") } + + OutlinedSlimButton(onClick = {}, enabled = false) { SingleLineText("Outlined Slim Disabled") } + } } } diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt index afb15cc4a2e6e..8110927f11fb4 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt @@ -43,6 +43,8 @@ import org.jetbrains.jewel.ui.component.styling.LocalMenuStyle import org.jetbrains.jewel.ui.component.styling.LocalOutlinedButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalOutlinedSplitButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalPopupContainerStyle +import org.jetbrains.jewel.ui.component.styling.LocalDefaultSlimButtonStyle +import org.jetbrains.jewel.ui.component.styling.LocalOutlinedSlimButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalRadioButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalScrollbarStyle import org.jetbrains.jewel.ui.component.styling.LocalSearchMatchStyle @@ -99,6 +101,8 @@ public class DefaultComponentStyling( public val linkStyle: LinkStyle, public val menuStyle: MenuStyle, public val outlinedButtonStyle: ButtonStyle, + public val defaultSlimButtonStyle: ButtonStyle, + public val outlinedSlimButtonStyle: ButtonStyle, public val popupContainerStyle: PopupContainerStyle, public val outlinedSplitButtonStyle: SplitButtonStyle, public val radioButtonStyle: RadioButtonStyle, @@ -137,6 +141,8 @@ public class DefaultComponentStyling( linkStyle: LinkStyle, menuStyle: MenuStyle, outlinedButtonStyle: ButtonStyle, + defaultSlimButtonStyle: ButtonStyle, + outlinedSlimButtonStyle: ButtonStyle, popupContainerStyle: PopupContainerStyle, outlinedSplitButtonStyle: SplitButtonStyle, radioButtonStyle: RadioButtonStyle, @@ -171,6 +177,8 @@ public class DefaultComponentStyling( linkStyle, menuStyle, outlinedButtonStyle, + defaultSlimButtonStyle, + outlinedSlimButtonStyle, popupContainerStyle, outlinedSplitButtonStyle, radioButtonStyle, @@ -209,6 +217,8 @@ public class DefaultComponentStyling( linkStyle: LinkStyle, menuStyle: MenuStyle, outlinedButtonStyle: ButtonStyle, + defaultSlimButtonStyle: ButtonStyle, + outlinedSlimButtonStyle: ButtonStyle, popupContainerStyle: PopupContainerStyle, outlinedSplitButtonStyle: SplitButtonStyle, radioButtonStyle: RadioButtonStyle, @@ -243,6 +253,8 @@ public class DefaultComponentStyling( linkStyle, menuStyle, outlinedButtonStyle, + defaultSlimButtonStyle, + outlinedSlimButtonStyle, popupContainerStyle, outlinedSplitButtonStyle, radioButtonStyle, @@ -285,6 +297,8 @@ public class DefaultComponentStyling( LocalLinkStyle provides linkStyle, LocalMenuStyle provides menuStyle, LocalOutlinedButtonStyle provides outlinedButtonStyle, + LocalDefaultSlimButtonStyle provides defaultSlimButtonStyle, + LocalOutlinedSlimButtonStyle provides outlinedSlimButtonStyle, LocalPopupContainerStyle provides popupContainerStyle, LocalOutlinedSplitButtonStyle provides outlinedSplitButtonStyle, LocalRadioButtonStyle provides radioButtonStyle, @@ -328,6 +342,8 @@ public class DefaultComponentStyling( if (linkStyle != other.linkStyle) return false if (menuStyle != other.menuStyle) return false if (outlinedButtonStyle != other.outlinedButtonStyle) return false + if (defaultSlimButtonStyle != other.defaultSlimButtonStyle) return false + if (outlinedSlimButtonStyle != other.outlinedSlimButtonStyle) return false if (popupContainerStyle != other.popupContainerStyle) return false if (outlinedSplitButtonStyle != other.outlinedSplitButtonStyle) return false if (radioButtonStyle != other.radioButtonStyle) return false @@ -368,6 +384,8 @@ public class DefaultComponentStyling( result = 31 * result + linkStyle.hashCode() result = 31 * result + menuStyle.hashCode() result = 31 * result + outlinedButtonStyle.hashCode() + result = 31 * result + defaultSlimButtonStyle.hashCode() + result = 31 * result + outlinedSlimButtonStyle.hashCode() result = 31 * result + popupContainerStyle.hashCode() result = 31 * result + outlinedSplitButtonStyle.hashCode() result = 31 * result + radioButtonStyle.hashCode() @@ -408,6 +426,8 @@ public class DefaultComponentStyling( "linkStyle=$linkStyle, " + "menuStyle=$menuStyle, " + "outlinedButtonStyle=$outlinedButtonStyle, " + + "defaultSlimButtonStyle=$defaultSlimButtonStyle, " + + "outlinedSlimButtonStyle=$outlinedSlimButtonStyle, " + "popupContainerStyle=$popupContainerStyle, " + "outlinedSplitButtonStyle=$outlinedSplitButtonStyle, " + "radioButtonStyle=$radioButtonStyle, " + diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt index 2ac69704f1f8c..f81a3fba71e1c 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Button.kt @@ -70,9 +70,11 @@ import org.jetbrains.jewel.ui.focusOutline import org.jetbrains.jewel.ui.icons.AllIconsKeys import org.jetbrains.jewel.ui.painter.hints.Stroke as PainterHintStroke import org.jetbrains.jewel.ui.theme.defaultButtonStyle +import org.jetbrains.jewel.ui.theme.defaultSlimButtonStyle import org.jetbrains.jewel.ui.theme.defaultSplitButtonStyle import org.jetbrains.jewel.ui.theme.menuStyle import org.jetbrains.jewel.ui.theme.outlinedButtonStyle +import org.jetbrains.jewel.ui.theme.outlinedSlimButtonStyle import org.jetbrains.jewel.ui.theme.outlinedSplitButtonStyle /** @@ -167,6 +169,101 @@ public fun OutlinedButton( ) } +/** + * A compact button with reduced padding and height, ideal for toolbars and space-constrained UIs. + * + * Mimics the appearance of toolbar buttons with `ActionToolbar.smallVariant = true`. Uses the default button visual + * treatment with compact metrics (24dp height vs 28dp for standard buttons). + * + * **Guidelines:** [on IJP SDK webhelp](https://plugins.jetbrains.com/docs/intellij/button.html) + * + * **Usage example:** + * [`Buttons.kt`](https://github.com/JetBrains/intellij-community/blob/master/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Buttons.kt) + * + * **Swing equivalent:** [`JButton`](https://docs.oracle.com/javase/tutorial/uiswing/components/button.html) with + * reduced insets + * + * @param onClick Will be called when the user clicks the button + * @param modifier Modifier to be applied to the button + * @param enabled Controls the enabled state of the button. When false, the button will not be clickable + * @param interactionSource An optional [MutableInteractionSource] for observing and emitting [Interaction]s for this + * button. Use this to observe state changes or customize interaction handling + * @param style The visual styling configuration for the button. Defaults to slim button style with default colors + * @param textStyle The typography style to be applied to the button's text content + * @param content The content to be displayed inside the button + * @see javax.swing.JButton + */ +@Composable +public fun DefaultSlimButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + style: ButtonStyle = JewelTheme.defaultSlimButtonStyle, + textStyle: TextStyle = JewelTheme.defaultTextStyle, + content: @Composable () -> Unit, +) { + ButtonImpl( + onClick = onClick, + modifier = modifier, + enabled = enabled, + forceFocused = false, + onStateChange = {}, + interactionSource = interactionSource, + style = style, + textStyle = textStyle, + content = content, + ) +} + +/** + * A compact button with outlined visual style, reduced padding and height, ideal for toolbars and space-constrained + * UIs. + * + * Similar to [DefaultSlimButton] but with an outlined visual treatment. Mimics the appearance of toolbar buttons with + * `ActionToolbar.smallVariant = true`, using compact metrics (24dp height vs 28dp for standard buttons). + * + * **Guidelines:** [on IJP SDK webhelp](https://plugins.jetbrains.com/docs/intellij/button.html) + * + * **Usage example:** + * [`Buttons.kt`](https://github.com/JetBrains/intellij-community/blob/master/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Buttons.kt) + * + * **Swing equivalent:** [`JButton`](https://docs.oracle.com/javase/tutorial/uiswing/components/button.html) with + * reduced insets + * + * @param onClick Will be called when the user clicks the button + * @param modifier Modifier to be applied to the button + * @param enabled Controls the enabled state of the button. When false, the button will not be clickable + * @param interactionSource An optional [MutableInteractionSource] for observing and emitting [Interaction]s for this + * button. Use this to observe state changes or customize interaction handling + * @param style The visual styling configuration for the button. Defaults to slim button style with outlined colors + * @param textStyle The typography style to be applied to the button's text content + * @param content The content to be displayed inside the button + * @see javax.swing.JButton + */ +@Composable +public fun OutlinedSlimButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + style: ButtonStyle = JewelTheme.outlinedSlimButtonStyle, + textStyle: TextStyle = JewelTheme.defaultTextStyle, + content: @Composable () -> Unit, +) { + ButtonImpl( + onClick = onClick, + modifier = modifier, + enabled = enabled, + forceFocused = false, + onStateChange = {}, + interactionSource = interactionSource, + style = style, + textStyle = textStyle, + content = content, + ) +} + /** * A split button combining a primary action with a dropdown menu, using an outlined visual style. * diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt index dc3575cb98592..82d30324cf639 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/styling/ButtonStyling.kt @@ -244,3 +244,11 @@ public val LocalDefaultButtonStyle: ProvidableCompositionLocal = st public val LocalOutlinedButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { error("No outlined ButtonStyle provided. Have you forgotten the theme?") } + +public val LocalDefaultSlimButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { + error("No default slim ButtonStyle provided. Have you forgotten the theme?") +} + +public val LocalOutlinedSlimButtonStyle: ProvidableCompositionLocal = staticCompositionLocalOf { + error("No outlined slim ButtonStyle provided. Have you forgotten the theme?") +} diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt index edfd99fbc3e6c..ca0645465f1e7 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/theme/JewelTheme.kt @@ -52,6 +52,8 @@ import org.jetbrains.jewel.ui.component.styling.LocalMenuStyle import org.jetbrains.jewel.ui.component.styling.LocalOutlinedButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalOutlinedSplitButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalPopupContainerStyle +import org.jetbrains.jewel.ui.component.styling.LocalDefaultSlimButtonStyle +import org.jetbrains.jewel.ui.component.styling.LocalOutlinedSlimButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalRadioButtonStyle import org.jetbrains.jewel.ui.component.styling.LocalScrollbarStyle import org.jetbrains.jewel.ui.component.styling.LocalSearchMatchStyle @@ -101,6 +103,12 @@ public val JewelTheme.Companion.defaultButtonStyle: ButtonStyle public val JewelTheme.Companion.outlinedButtonStyle: ButtonStyle @Composable @ReadOnlyComposable get() = LocalOutlinedButtonStyle.current +public val JewelTheme.Companion.defaultSlimButtonStyle: ButtonStyle + @Composable @ReadOnlyComposable get() = LocalDefaultSlimButtonStyle.current + +public val JewelTheme.Companion.outlinedSlimButtonStyle: ButtonStyle + @Composable @ReadOnlyComposable get() = LocalOutlinedSlimButtonStyle.current + public val JewelTheme.Companion.defaultSplitButtonStyle: SplitButtonStyle @Composable @ReadOnlyComposable get() = LocalDefaultSplitButtonStyle.current