Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ internal fun createBridgeComponentStyling(theme: ThemeDefinition): ComponentStyl
val menuStyle = readMenuStyle()

return DefaultComponentStyling(
badgeStyle = readBadgeStyle(),
checkboxStyle = readCheckboxStyle(),
chipStyle = readChipStyle(),
circularProgressStyle = readCircularProgressStyle(theme.isDark),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jetbrains.jewel.bridge.theme

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.bridge.createVerticalBrush
import org.jetbrains.jewel.bridge.retrieveColorOrUnspecified
import org.jetbrains.jewel.bridge.retrieveColorsOrUnspecified
import org.jetbrains.jewel.ui.component.styling.BadgeColors
import org.jetbrains.jewel.ui.component.styling.BadgeMetrics
import org.jetbrains.jewel.ui.component.styling.BadgeStyle

// Note: there isn't a badge spec in the IntelliJ Platform LaF, so we're deriving
// this from similar small promotional UI elements.
// Badges are small colored elements used to display promotional text like "New", "Beta", etc.
internal fun readBadgeStyle(): BadgeStyle {
val normalBackground =
retrieveColorsOrUnspecified("Button.startBackground", "Button.endBackground").createVerticalBrush()

val normalContent = retrieveColorOrUnspecified("Label.foreground")
val disabledContent = retrieveColorOrUnspecified("Label.disabledForeground").takeOrElse { normalContent }

val colors =
BadgeColors(
background = normalBackground,
backgroundDisabled = normalBackground,
backgroundFocused = normalBackground,
backgroundPressed = normalBackground,
backgroundHovered = normalBackground,
content = normalContent,
contentDisabled = disabledContent,
contentFocused = normalContent,
contentPressed = normalContent,
contentHovered = normalContent,
)
Comment on lines +19 to +37
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem all wrong, according to the specs:

Image

Please do triple check the keys in the spec are correct since the Swing impl is notorious for not following specs — 1:1 fidelity to the actual implementation trumps specs


return BadgeStyle(
colors = colors,
metrics =
BadgeMetrics(
cornerSize = CornerSize(0.dp),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Badges are only available as pills, as per specs; not sure why the corner size is zero where it should be 100%:

Image

padding = PaddingValues(horizontal = 6.dp, vertical = 2.dp),
minSize = DpSize(32.dp, 18.dp),
Comment on lines +44 to +45
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image

There should be no min width, and the height is fixed at 16.dp (not a minimum). Also no vertical padding — I assume we should centre the Text vertically instead.

),
)
}
19 changes: 17 additions & 2 deletions platform/jewel/int-ui/int-ui-standalone/api-dump.txt

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.jetbrains.jewel.intui.standalone.styling

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
import org.jetbrains.jewel.intui.core.theme.IntUiLightTheme
import org.jetbrains.jewel.ui.component.styling.BadgeColors
import org.jetbrains.jewel.ui.component.styling.BadgeMetrics
import org.jetbrains.jewel.ui.component.styling.BadgeStyle

public fun BadgeStyle.Companion.light(
colors: BadgeColors = BadgeColors.light(),
metrics: BadgeMetrics = BadgeMetrics.defaults(),
): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics)

public fun BadgeStyle.Companion.dark(
colors: BadgeColors = BadgeColors.dark(),
metrics: BadgeMetrics = BadgeMetrics.defaults(),
): BadgeStyle = BadgeStyle(colors = colors, metrics = metrics)
Comment on lines +16 to +24
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the specs, we have 6 default badge styles (blue, bluePrimary, green, greenPrimary, purple, gray) — plus the disabled state, which is the same for all of them:

Image

So we should have a BridgeStyles that contains styling for all the 6 variants, and that has a light and a dark variant creation


public fun BadgeColors.Companion.light(
background: Brush = SolidColor(IntUiLightTheme.colors.blue(4)),
backgroundDisabled: Brush = SolidColor(IntUiLightTheme.colors.gray(12)),
backgroundFocused: Brush = SolidColor(IntUiLightTheme.colors.blue(5)),
backgroundPressed: Brush = SolidColor(IntUiLightTheme.colors.blue(6)),
backgroundHovered: Brush = SolidColor(IntUiLightTheme.colors.blue(5)),
content: Color = IntUiLightTheme.colors.gray(14),
contentDisabled: Color = IntUiLightTheme.colors.gray(8),
contentFocused: Color = IntUiLightTheme.colors.gray(14),
contentPressed: Color = IntUiLightTheme.colors.gray(14),
contentHovered: Color = IntUiLightTheme.colors.gray(14),
): BadgeColors =
Comment on lines +26 to +37
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QQ: Where have you found those values? They don't match StandAlone/IDE:

Image

BadgeColors(
background = background,
backgroundDisabled = backgroundDisabled,
backgroundFocused = backgroundFocused,
backgroundPressed = backgroundPressed,
backgroundHovered = backgroundHovered,
content = content,
contentDisabled = contentDisabled,
contentFocused = contentFocused,
contentPressed = contentPressed,
contentHovered = contentHovered,
)

public fun BadgeColors.Companion.dark(
background: Brush = SolidColor(IntUiDarkTheme.colors.blue(6)),
backgroundDisabled: Brush = SolidColor(IntUiDarkTheme.colors.gray(3)),
backgroundFocused: Brush = SolidColor(IntUiDarkTheme.colors.blue(5)),
backgroundPressed: Brush = SolidColor(IntUiDarkTheme.colors.blue(7)),
backgroundHovered: Brush = SolidColor(IntUiDarkTheme.colors.blue(5)),
content: Color = IntUiDarkTheme.colors.gray(14),
contentDisabled: Color = IntUiDarkTheme.colors.gray(8),
contentFocused: Color = IntUiDarkTheme.colors.gray(14),
contentPressed: Color = IntUiDarkTheme.colors.gray(14),
contentHovered: Color = IntUiDarkTheme.colors.gray(14),
): BadgeColors =
BadgeColors(
background = background,
backgroundDisabled = backgroundDisabled,
backgroundFocused = backgroundFocused,
backgroundPressed = backgroundPressed,
backgroundHovered = backgroundHovered,
content = content,
contentDisabled = contentDisabled,
contentFocused = contentFocused,
contentPressed = contentPressed,
contentHovered = contentHovered,
)

public fun BadgeMetrics.Companion.defaults(
cornerSize: CornerSize = CornerSize(0.dp),
padding: PaddingValues = PaddingValues(horizontal = 6.dp, vertical = 2.dp),
minSize: DpSize = DpSize(32.dp, 18.dp),
): BadgeMetrics = BadgeMetrics(cornerSize = cornerSize, padding = padding, minSize = minSize)
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,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.BadgeStyle
import org.jetbrains.jewel.ui.component.styling.ButtonStyle
import org.jetbrains.jewel.ui.component.styling.CheckboxStyle
import org.jetbrains.jewel.ui.component.styling.ChipStyle
Expand Down Expand Up @@ -243,6 +244,7 @@ public fun ComponentStyling.default(): ComponentStyling = with {

@Suppress("UnusedReceiverParameter")
public fun ComponentStyling.dark(
badgeStyle: BadgeStyle = BadgeStyle.dark(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Prioritize adding new params in the end to prevent breaking changes if the developer do not use named attributes

checkboxStyle: CheckboxStyle = CheckboxStyle.dark(),
chipStyle: ChipStyle = ChipStyle.dark(),
circularProgressStyle: CircularProgressStyle = CircularProgressStyle.dark(),
Expand Down Expand Up @@ -280,6 +282,85 @@ public fun ComponentStyling.dark(
searchMatchStyle: SearchMatchStyle = SearchMatchStyle.dark(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = badgeStyle,
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
defaultBannerStyle = defaultBannerStyle,
comboBoxStyle = comboBoxStyle,
defaultButtonStyle = defaultButtonStyle,
defaultDropdownStyle = dropdownStyle,
defaultSplitButtonStyle = defaultSplitButtonStyle,
defaultTabStyle = defaultTabStyle,
dividerStyle = dividerStyle,
editorTabStyle = editorTabStyle,
groupHeaderStyle = groupHeaderStyle,
horizontalProgressBarStyle = horizontalProgressBarStyle,
iconButtonStyle = iconButtonStyle,
transparentIconButtonStyle = transparentIconButtonStyle,
inlineBannerStyle = inlineBannerStyle,
lazyTreeStyle = lazyTreeStyle,
linkStyle = linkStyle,
menuStyle = menuStyle,
outlinedButtonStyle = outlinedButtonStyle,
popupContainerStyle = popupContainerStyle,
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
radioButtonStyle = radioButtonStyle,
scrollbarStyle = scrollbarStyle,
segmentedControlButtonStyle = segmentedControlButtonStyle,
segmentedControlStyle = segmentedControlStyle,
selectableLazyColumnStyle = selectableLazyColumnStyle,
simpleListItemStyle = simpleListItemStyle,
sliderStyle = sliderStyle,
textAreaStyle = textAreaStyle,
textFieldStyle = textFieldStyle,
tooltipStyle = tooltipStyle,
undecoratedDropdownStyle = undecoratedDropdownStyle,
speedSearchStyle = speedSearchStyle,
searchMatchStyle = searchMatchStyle,
)

@Suppress("UnusedReceiverParameter", "DEPRECATION_ERROR")
@Deprecated("Use the variant with badgeStyle.", level = DeprecationLevel.HIDDEN)
public fun ComponentStyling.dark(
checkboxStyle: CheckboxStyle = CheckboxStyle.dark(),
chipStyle: ChipStyle = ChipStyle.dark(),
circularProgressStyle: CircularProgressStyle = CircularProgressStyle.dark(),
defaultBannerStyle: DefaultBannerStyles = DefaultBannerStyles.Default.dark(),
comboBoxStyle: ComboBoxStyle = ComboBoxStyle.Default.dark(),
defaultButtonStyle: ButtonStyle = ButtonStyle.Default.dark(),
defaultSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Default.dark(),
defaultTabStyle: TabStyle = TabStyle.Default.dark(),
dividerStyle: DividerStyle = DividerStyle.dark(),
dropdownStyle: DropdownStyle = DropdownStyle.Default.dark(),
editorTabStyle: TabStyle = TabStyle.Editor.dark(),
groupHeaderStyle: GroupHeaderStyle = GroupHeaderStyle.dark(),
horizontalProgressBarStyle: HorizontalProgressBarStyle = HorizontalProgressBarStyle.dark(),
iconButtonStyle: IconButtonStyle = IconButtonStyle.dark(),
transparentIconButtonStyle: IconButtonStyle = IconButtonStyle.darkTransparentBackground(),
inlineBannerStyle: InlineBannerStyles = InlineBannerStyles.Default.dark(),
lazyTreeStyle: LazyTreeStyle = LazyTreeStyle.dark(),
linkStyle: LinkStyle = LinkStyle.dark(),
menuStyle: MenuStyle = MenuStyle.dark(),
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(),
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(),
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(),
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(),
scrollbarStyle: ScrollbarStyle = ScrollbarStyle.dark(),
segmentedControlButtonStyle: SegmentedControlButtonStyle = SegmentedControlButtonStyle.dark(),
segmentedControlStyle: SegmentedControlStyle = SegmentedControlStyle.dark(),
selectableLazyColumnStyle: SelectableLazyColumnStyle = SelectableLazyColumnStyle.dark(),
sliderStyle: SliderStyle = SliderStyle.dark(),
simpleListItemStyle: SimpleListItemStyle = SimpleListItemStyle.dark(),
textAreaStyle: TextAreaStyle = TextAreaStyle.dark(),
textFieldStyle: TextFieldStyle = TextFieldStyle.dark(),
tooltipStyle: TooltipStyle = TooltipStyle.dark(autoHideBehavior = TooltipAutoHideBehavior.Normal),
undecoratedDropdownStyle: DropdownStyle = DropdownStyle.Undecorated.dark(),
speedSearchStyle: SpeedSearchStyle = SpeedSearchStyle.dark(),
searchMatchStyle: SearchMatchStyle = SearchMatchStyle.dark(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = BadgeStyle.dark(),
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
Expand Down Expand Up @@ -355,6 +436,7 @@ public fun ComponentStyling.dark(
undecoratedDropdownStyle: DropdownStyle = DropdownStyle.Undecorated.dark(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = BadgeStyle.dark(),
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
Expand Down Expand Up @@ -429,6 +511,7 @@ public fun ComponentStyling.dark(
undecoratedDropdownStyle: DropdownStyle = DropdownStyle.Undecorated.dark(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = BadgeStyle.dark(),
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
Expand Down Expand Up @@ -467,6 +550,85 @@ public fun ComponentStyling.dark(
)

@Suppress("UnusedReceiverParameter")
public fun ComponentStyling.light(
badgeStyle: BadgeStyle = BadgeStyle.light(),
checkboxStyle: CheckboxStyle = CheckboxStyle.light(),
chipStyle: ChipStyle = ChipStyle.light(),
circularProgressStyle: CircularProgressStyle = CircularProgressStyle.light(),
defaultBannerStyle: DefaultBannerStyles = DefaultBannerStyles.Default.light(),
comboBoxStyle: ComboBoxStyle = ComboBoxStyle.Default.light(),
defaultButtonStyle: ButtonStyle = ButtonStyle.Default.light(),
defaultSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Default.light(),
defaultTabStyle: TabStyle = TabStyle.Default.light(),
dividerStyle: DividerStyle = DividerStyle.light(),
dropdownStyle: DropdownStyle = DropdownStyle.Default.light(),
editorTabStyle: TabStyle = TabStyle.Editor.light(),
groupHeaderStyle: GroupHeaderStyle = GroupHeaderStyle.light(),
horizontalProgressBarStyle: HorizontalProgressBarStyle = HorizontalProgressBarStyle.light(),
iconButtonStyle: IconButtonStyle = IconButtonStyle.light(),
transparentIconButtonStyle: IconButtonStyle = IconButtonStyle.lightTransparentBackground(),
inlineBannerStyle: InlineBannerStyles = InlineBannerStyles.Default.light(),
lazyTreeStyle: LazyTreeStyle = LazyTreeStyle.light(),
linkStyle: LinkStyle = LinkStyle.light(),
menuStyle: MenuStyle = MenuStyle.light(),
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(),
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(),
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(),
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.light(),
scrollbarStyle: ScrollbarStyle = ScrollbarStyle.light(),
segmentedControlButtonStyle: SegmentedControlButtonStyle = SegmentedControlButtonStyle.light(),
segmentedControlStyle: SegmentedControlStyle = SegmentedControlStyle.light(),
sliderStyle: SliderStyle = SliderStyle.light(),
selectableLazyColumnStyle: SelectableLazyColumnStyle = SelectableLazyColumnStyle.light(),
simpleListItemStyle: SimpleListItemStyle = SimpleListItemStyle.light(),
textAreaStyle: TextAreaStyle = TextAreaStyle.light(),
textFieldStyle: TextFieldStyle = TextFieldStyle.light(),
tooltipStyle: TooltipStyle = TooltipStyle.light(autoHideBehavior = TooltipAutoHideBehavior.Normal),
undecoratedDropdownStyle: DropdownStyle = DropdownStyle.Undecorated.light(),
speedSearchStyle: SpeedSearchStyle = SpeedSearchStyle.light(),
searchMatchStyle: SearchMatchStyle = SearchMatchStyle.light(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = badgeStyle,
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
comboBoxStyle = comboBoxStyle,
defaultBannerStyle = defaultBannerStyle,
defaultButtonStyle = defaultButtonStyle,
defaultDropdownStyle = dropdownStyle,
defaultSplitButtonStyle = defaultSplitButtonStyle,
defaultTabStyle = defaultTabStyle,
dividerStyle = dividerStyle,
editorTabStyle = editorTabStyle,
groupHeaderStyle = groupHeaderStyle,
horizontalProgressBarStyle = horizontalProgressBarStyle,
iconButtonStyle = iconButtonStyle,
transparentIconButtonStyle = transparentIconButtonStyle,
inlineBannerStyle = inlineBannerStyle,
lazyTreeStyle = lazyTreeStyle,
linkStyle = linkStyle,
menuStyle = menuStyle,
outlinedButtonStyle = outlinedButtonStyle,
popupContainerStyle = popupContainerStyle,
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
radioButtonStyle = radioButtonStyle,
scrollbarStyle = scrollbarStyle,
segmentedControlButtonStyle = segmentedControlButtonStyle,
segmentedControlStyle = segmentedControlStyle,
selectableLazyColumnStyle = selectableLazyColumnStyle,
sliderStyle = sliderStyle,
simpleListItemStyle = simpleListItemStyle,
textAreaStyle = textAreaStyle,
textFieldStyle = textFieldStyle,
tooltipStyle = tooltipStyle,
undecoratedDropdownStyle = undecoratedDropdownStyle,
speedSearchStyle = speedSearchStyle,
searchMatchStyle = searchMatchStyle,
)

@Suppress("UnusedReceiverParameter", "DEPRECATION_ERROR")
@Deprecated("Use the variant with badgeStyle.", level = DeprecationLevel.HIDDEN)
public fun ComponentStyling.light(
checkboxStyle: CheckboxStyle = CheckboxStyle.light(),
chipStyle: ChipStyle = ChipStyle.light(),
Expand Down Expand Up @@ -505,6 +667,7 @@ public fun ComponentStyling.light(
searchMatchStyle: SearchMatchStyle = SearchMatchStyle.light(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = BadgeStyle.light(),
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
Expand Down Expand Up @@ -580,6 +743,7 @@ public fun ComponentStyling.light(
undecoratedDropdownStyle: DropdownStyle = DropdownStyle.Undecorated.light(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = BadgeStyle.light(),
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
Expand Down Expand Up @@ -654,6 +818,7 @@ public fun ComponentStyling.light(
undecoratedDropdownStyle: DropdownStyle = DropdownStyle.Undecorated.light(),
): ComponentStyling =
DefaultComponentStyling(
badgeStyle = BadgeStyle.light(),
checkboxStyle = checkboxStyle,
chipStyle = chipStyle,
circularProgressStyle = circularProgressStyle,
Expand Down
3 changes: 3 additions & 0 deletions platform/jewel/samples/showcase/api-dump.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ f:org.jetbrains.jewel.samples.showcase.ShowcaseIcons
f:org.jetbrains.jewel.samples.showcase.ShowcaseIcons$Components
- sf:$stable:I
- sf:INSTANCE:org.jetbrains.jewel.samples.showcase.ShowcaseIcons$Components
- f:getBadge():org.jetbrains.jewel.ui.icon.PathIconKey
- f:getBanners():org.jetbrains.jewel.ui.icon.PathIconKey
- f:getBorders():org.jetbrains.jewel.ui.icon.PathIconKey
- f:getBrush():org.jetbrains.jewel.ui.icon.PathIconKey
Expand All @@ -38,6 +39,8 @@ f:org.jetbrains.jewel.samples.showcase.ShowcaseIcons$ProgrammingLanguages
- sf:$stable:I
- sf:INSTANCE:org.jetbrains.jewel.samples.showcase.ShowcaseIcons$ProgrammingLanguages
- f:getKotlin():org.jetbrains.jewel.ui.icon.PathIconKey
f:org.jetbrains.jewel.samples.showcase.components.BadgesKt
- sf:Badges(androidx.compose.ui.Modifier,androidx.compose.runtime.Composer,I,I):V
f:org.jetbrains.jewel.samples.showcase.components.BannersKt
- sf:Banners(androidx.compose.ui.Modifier,androidx.compose.runtime.Composer,I,I):V
f:org.jetbrains.jewel.samples.showcase.components.BordersKt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public object ShowcaseIcons {
public val sunny: PathIconKey = PathIconKey("icons/sunny.svg", ShowcaseIcons::class.java)

public object Components {
public val badge: PathIconKey = PathIconKey("icons/components/badge.svg", ShowcaseIcons::class.java)
public val banners: PathIconKey = PathIconKey("icons/components/banners.svg", ShowcaseIcons::class.java)
public val borders: PathIconKey = PathIconKey("icons/components/borders.svg", ShowcaseIcons::class.java)
public val brush: PathIconKey = PathIconKey("icons/components/brush.svg", ShowcaseIcons::class.java)
Expand Down
Loading
Loading