Skip to content

Commit c4d0b61

Browse files
[JEWEL-954] Implement ad text in popups
1 parent 825bdac commit c4d0b61

File tree

13 files changed

+363
-2
lines changed

13 files changed

+363
-2
lines changed

platform/jewel/ide-laf-bridge/src/main/kotlin/org/jetbrains/jewel/bridge/theme/IntUiBridge.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ internal fun createBridgeComponentStyling(theme: ThemeDefinition): ComponentStyl
9090
menuStyle = menuStyle,
9191
outlinedButtonStyle = readOutlinedButtonStyle(),
9292
outlinedSplitButtonStyle = readOutlinedSplitButtonStyle(),
93+
popupAdTextStyle = readPopupAdTextStyle(),
9394
popupContainerStyle = readPopupContainerStyle(),
9495
radioButtonStyle = readRadioButtonStyle(),
9596
scrollbarStyle = readScrollbarStyle(theme.isDark),
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.jetbrains.jewel.bridge.theme
2+
3+
import androidx.compose.foundation.layout.PaddingValues
4+
import androidx.compose.ui.graphics.takeOrElse
5+
import androidx.compose.ui.text.TextStyle
6+
import androidx.compose.ui.text.font.FontFamily
7+
import androidx.compose.ui.unit.dp
8+
import androidx.compose.ui.unit.sp
9+
import com.intellij.ui.NewUiValue
10+
import com.intellij.util.ui.JBUI
11+
import org.jetbrains.jewel.bridge.dp
12+
import org.jetbrains.jewel.bridge.retrieveColorOrUnspecified
13+
import org.jetbrains.jewel.bridge.retrieveInsetsAsPaddingValues
14+
import org.jetbrains.jewel.bridge.toComposeColor
15+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextColors
16+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextMetrics
17+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextStyle
18+
19+
internal fun readPopupAdTextStyle(): PopupAdTextStyle {
20+
// Get colors from LaF following JBUI.CurrentTheme.Advertiser pattern
21+
// Uses Popup.Advertiser.* keys with fallback to SearchEverywhere.Advertiser.*
22+
val foregroundColor = retrieveColorOrUnspecified("Popup.Advertiser.foreground").takeOrElse {
23+
retrieveColorOrUnspecified("SearchEverywhere.Advertiser.foreground").takeOrElse {
24+
JBUI.CurrentTheme.Advertiser.foreground().toComposeColor()
25+
}
26+
}
27+
28+
val backgroundColor = retrieveColorOrUnspecified("Popup.Advertiser.background").takeOrElse {
29+
retrieveColorOrUnspecified("SearchEverywhere.Advertiser.background").takeOrElse {
30+
JBUI.CurrentTheme.Advertiser.background().toComposeColor()
31+
}
32+
}
33+
34+
val colors = PopupAdTextColors(
35+
foreground = foregroundColor,
36+
background = backgroundColor,
37+
)
38+
39+
// Get border insets from LaF following JBUI.CurrentTheme.Advertiser.borderInsets() pattern
40+
// For new UI: insets(6, 20), for legacy UI: insets(5, 10, 5, 15)
41+
val borderInsets = retrieveInsetsAsPaddingValues("Popup.Advertiser.borderInsets")
42+
?: if (NewUiValue.isEnabled()) {
43+
// New UI default
44+
PaddingValues(horizontal = 20.dp, vertical = 6.dp)
45+
} else {
46+
// Legacy UI default
47+
PaddingValues(start = 15.dp, top = 5.dp, end = 10.dp, bottom = 5.dp)
48+
}
49+
50+
// Get font size offset from LaF following JBUI.CurrentTheme.Advertiser.FONT_SIZE_OFFSET
51+
// Default is -2 (making font slightly smaller)
52+
val fontSizeOffset = uiDefaults.getInt("Popup.Advertiser.fontSizeOffset")
53+
.takeIf { it != 0 } ?: -2
54+
55+
val baseFontSize = uiDefaults.getFont("Label.font")?.size ?: 13
56+
val fontSize = (baseFontSize + fontSizeOffset).coerceAtLeast(9)
57+
58+
val metrics = PopupAdTextMetrics(
59+
padding = borderInsets,
60+
minHeight = 20.dp,
61+
spacerHeight = 4.dp,
62+
)
63+
64+
val textStyle = TextStyle(
65+
fontSize = fontSize.sp,
66+
fontFamily = FontFamily.Default,
67+
)
68+
69+
return PopupAdTextStyle(
70+
colors = colors,
71+
metrics = metrics,
72+
textStyle = textStyle,
73+
)
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
2+
package org.jetbrains.jewel.intui.standalone.styling
3+
4+
import androidx.compose.foundation.layout.PaddingValues
5+
import androidx.compose.ui.graphics.Color
6+
import androidx.compose.ui.text.TextStyle
7+
import androidx.compose.ui.unit.dp
8+
import androidx.compose.ui.unit.sp
9+
import org.jetbrains.jewel.intui.core.theme.IntUiDarkTheme
10+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextColors
11+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextMetrics
12+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextStyle
13+
14+
public fun PopupAdTextStyle.Companion.light(): PopupAdTextStyle = PopupAdTextStyle(
15+
colors = PopupAdTextColors(
16+
foreground = Color.Gray,
17+
background = Color(0xFFF2F2F2),
18+
),
19+
metrics = PopupAdTextMetrics(
20+
padding = PaddingValues(horizontal = 20.dp, vertical = 6.dp),
21+
minHeight = 20.dp,
22+
spacerHeight = 4.dp,
23+
),
24+
textStyle = TextStyle(
25+
fontSize = 11.sp,
26+
),
27+
)
28+
29+
public fun PopupAdTextStyle.Companion.dark(): PopupAdTextStyle = PopupAdTextStyle(
30+
colors = PopupAdTextColors(
31+
foreground = Color.LightGray,
32+
background = IntUiDarkTheme.colors.grayOrNull(2) ?: Color(0xFF2B2B2B),
33+
),
34+
metrics = PopupAdTextMetrics(
35+
padding = PaddingValues(horizontal = 20.dp, vertical = 6.dp),
36+
minHeight = 20.dp,
37+
spacerHeight = 4.dp,
38+
),
39+
textStyle = TextStyle(
40+
fontSize = 11.sp,
41+
),
42+
)

platform/jewel/int-ui/int-ui-standalone/src/main/kotlin/org/jetbrains/jewel/intui/standalone/theme/IntUiTheme.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import org.jetbrains.jewel.ui.component.styling.InlineBannerStyles
5050
import org.jetbrains.jewel.ui.component.styling.LazyTreeStyle
5151
import org.jetbrains.jewel.ui.component.styling.LinkStyle
5252
import org.jetbrains.jewel.ui.component.styling.MenuStyle
53+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextStyle
5354
import org.jetbrains.jewel.ui.component.styling.PopupContainerStyle
5455
import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle
5556
import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle
@@ -263,6 +264,7 @@ public fun ComponentStyling.dark(
263264
linkStyle: LinkStyle = LinkStyle.dark(),
264265
menuStyle: MenuStyle = MenuStyle.dark(),
265266
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(),
267+
popupAdTextStyle: PopupAdTextStyle = PopupAdTextStyle.dark(),
266268
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(),
267269
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(),
268270
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(),
@@ -300,6 +302,7 @@ public fun ComponentStyling.dark(
300302
linkStyle = linkStyle,
301303
menuStyle = menuStyle,
302304
outlinedButtonStyle = outlinedButtonStyle,
305+
popupAdTextStyle = popupAdTextStyle,
303306
popupContainerStyle = popupContainerStyle,
304307
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
305308
radioButtonStyle = radioButtonStyle,
@@ -340,6 +343,7 @@ public fun ComponentStyling.dark(
340343
linkStyle: LinkStyle = LinkStyle.dark(),
341344
menuStyle: MenuStyle = MenuStyle.dark(),
342345
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(),
346+
popupAdTextStyle: PopupAdTextStyle = PopupAdTextStyle.dark(),
343347
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(),
344348
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(),
345349
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(),
@@ -375,6 +379,7 @@ public fun ComponentStyling.dark(
375379
linkStyle = linkStyle,
376380
menuStyle = menuStyle,
377381
outlinedButtonStyle = outlinedButtonStyle,
382+
popupAdTextStyle = popupAdTextStyle,
378383
popupContainerStyle = popupContainerStyle,
379384
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
380385
radioButtonStyle = radioButtonStyle,
@@ -414,6 +419,7 @@ public fun ComponentStyling.dark(
414419
linkStyle: LinkStyle = LinkStyle.dark(),
415420
menuStyle: MenuStyle = MenuStyle.dark(),
416421
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.dark(),
422+
popupAdTextStyle: PopupAdTextStyle = PopupAdTextStyle.dark(),
417423
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.dark(),
418424
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.dark(),
419425
radioButtonStyle: RadioButtonStyle = RadioButtonStyle.dark(),
@@ -449,6 +455,7 @@ public fun ComponentStyling.dark(
449455
linkStyle = linkStyle,
450456
menuStyle = menuStyle,
451457
outlinedButtonStyle = outlinedButtonStyle,
458+
popupAdTextStyle = popupAdTextStyle,
452459
popupContainerStyle = popupContainerStyle,
453460
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
454461
radioButtonStyle = radioButtonStyle,
@@ -487,6 +494,7 @@ public fun ComponentStyling.light(
487494
lazyTreeStyle: LazyTreeStyle = LazyTreeStyle.light(),
488495
linkStyle: LinkStyle = LinkStyle.light(),
489496
menuStyle: MenuStyle = MenuStyle.light(),
497+
popupAdTextStyle: PopupAdTextStyle = PopupAdTextStyle.light(),
490498
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(),
491499
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(),
492500
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(),
@@ -525,6 +533,7 @@ public fun ComponentStyling.light(
525533
linkStyle = linkStyle,
526534
menuStyle = menuStyle,
527535
outlinedButtonStyle = outlinedButtonStyle,
536+
popupAdTextStyle = popupAdTextStyle,
528537
popupContainerStyle = popupContainerStyle,
529538
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
530539
radioButtonStyle = radioButtonStyle,
@@ -564,6 +573,7 @@ public fun ComponentStyling.light(
564573
lazyTreeStyle: LazyTreeStyle = LazyTreeStyle.light(),
565574
linkStyle: LinkStyle = LinkStyle.light(),
566575
menuStyle: MenuStyle = MenuStyle.light(),
576+
popupAdTextStyle: PopupAdTextStyle = PopupAdTextStyle.light(),
567577
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(),
568578
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(),
569579
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(),
@@ -600,6 +610,7 @@ public fun ComponentStyling.light(
600610
linkStyle = linkStyle,
601611
menuStyle = menuStyle,
602612
outlinedButtonStyle = outlinedButtonStyle,
613+
popupAdTextStyle = popupAdTextStyle,
603614
popupContainerStyle = popupContainerStyle,
604615
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
605616
radioButtonStyle = radioButtonStyle,
@@ -638,6 +649,7 @@ public fun ComponentStyling.light(
638649
lazyTreeStyle: LazyTreeStyle = LazyTreeStyle.light(),
639650
linkStyle: LinkStyle = LinkStyle.light(),
640651
menuStyle: MenuStyle = MenuStyle.light(),
652+
popupAdTextStyle: PopupAdTextStyle = PopupAdTextStyle.light(),
641653
popupContainerStyle: PopupContainerStyle = PopupContainerStyle.light(),
642654
outlinedButtonStyle: ButtonStyle = ButtonStyle.Outlined.light(),
643655
outlinedSplitButtonStyle: SplitButtonStyle = SplitButtonStyle.Outlined.light(),
@@ -674,6 +686,7 @@ public fun ComponentStyling.light(
674686
linkStyle = linkStyle,
675687
menuStyle = menuStyle,
676688
outlinedButtonStyle = outlinedButtonStyle,
689+
popupAdTextStyle = popupAdTextStyle,
677690
popupContainerStyle = popupContainerStyle,
678691
outlinedSplitButtonStyle = outlinedSplitButtonStyle,
679692
radioButtonStyle = radioButtonStyle,

platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ComboBoxes.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ public fun ComboBoxes(modifier: Modifier = Modifier) {
8787
GroupHeader("Editable list combo box")
8888
EditableListComboBoxes()
8989

90+
GroupHeader("Editable list combo box with ad text")
91+
EditableListComboBoxesWithAdText()
92+
9093
GroupHeader("Custom combo box content")
9194
CustomComboBoxes()
9295

@@ -247,6 +250,25 @@ private fun EditableListComboBoxes() {
247250
}
248251
}
249252

253+
@Composable
254+
private fun EditableListComboBoxesWithAdText() {
255+
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
256+
Column(Modifier.weight(1f).widthIn(min = 125.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
257+
Text("Ad text example")
258+
var selectedIndex by remember { mutableIntStateOf(0) }
259+
InfoText(text = "Editable combo box with hints")
260+
261+
EditableListComboBox(
262+
items = listOf("Focused", "Balance", "Creative"),
263+
adText = "Balance between the number of code suggestions and error filtration",
264+
selectedIndex = selectedIndex,
265+
onSelectedItemChange = { index -> selectedIndex = index },
266+
modifier = Modifier.widthIn(max = 200.dp).fillMaxWidth(),
267+
)
268+
}
269+
}
270+
}
271+
250272
@Composable
251273
private fun CustomComboBoxes() {
252274
FlowRow(horizontalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {

platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/DefaultComponentStyling.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import org.jetbrains.jewel.ui.component.styling.LocalLinkStyle
4242
import org.jetbrains.jewel.ui.component.styling.LocalMenuStyle
4343
import org.jetbrains.jewel.ui.component.styling.LocalOutlinedButtonStyle
4444
import org.jetbrains.jewel.ui.component.styling.LocalOutlinedSplitButtonStyle
45+
import org.jetbrains.jewel.ui.component.styling.LocalPopupAdTextStyle
4546
import org.jetbrains.jewel.ui.component.styling.LocalPopupContainerStyle
4647
import org.jetbrains.jewel.ui.component.styling.LocalRadioButtonStyle
4748
import org.jetbrains.jewel.ui.component.styling.LocalScrollbarStyle
@@ -58,6 +59,7 @@ import org.jetbrains.jewel.ui.component.styling.LocalTooltipStyle
5859
import org.jetbrains.jewel.ui.component.styling.LocalTransparentIconButtonStyle
5960
import org.jetbrains.jewel.ui.component.styling.LocalUndecoratedDropdownStyle
6061
import org.jetbrains.jewel.ui.component.styling.MenuStyle
62+
import org.jetbrains.jewel.ui.component.styling.PopupAdTextStyle
6163
import org.jetbrains.jewel.ui.component.styling.PopupContainerStyle
6264
import org.jetbrains.jewel.ui.component.styling.RadioButtonStyle
6365
import org.jetbrains.jewel.ui.component.styling.ScrollbarStyle
@@ -99,6 +101,7 @@ public class DefaultComponentStyling(
99101
public val linkStyle: LinkStyle,
100102
public val menuStyle: MenuStyle,
101103
public val outlinedButtonStyle: ButtonStyle,
104+
public val popupAdTextStyle: PopupAdTextStyle,
102105
public val popupContainerStyle: PopupContainerStyle,
103106
public val outlinedSplitButtonStyle: SplitButtonStyle,
104107
public val radioButtonStyle: RadioButtonStyle,
@@ -137,6 +140,7 @@ public class DefaultComponentStyling(
137140
linkStyle: LinkStyle,
138141
menuStyle: MenuStyle,
139142
outlinedButtonStyle: ButtonStyle,
143+
popupAdTextStyle: PopupAdTextStyle,
140144
popupContainerStyle: PopupContainerStyle,
141145
outlinedSplitButtonStyle: SplitButtonStyle,
142146
radioButtonStyle: RadioButtonStyle,
@@ -171,6 +175,7 @@ public class DefaultComponentStyling(
171175
linkStyle,
172176
menuStyle,
173177
outlinedButtonStyle,
178+
popupAdTextStyle,
174179
popupContainerStyle,
175180
outlinedSplitButtonStyle,
176181
radioButtonStyle,
@@ -209,6 +214,7 @@ public class DefaultComponentStyling(
209214
linkStyle: LinkStyle,
210215
menuStyle: MenuStyle,
211216
outlinedButtonStyle: ButtonStyle,
217+
popupAdTextStyle: PopupAdTextStyle,
212218
popupContainerStyle: PopupContainerStyle,
213219
outlinedSplitButtonStyle: SplitButtonStyle,
214220
radioButtonStyle: RadioButtonStyle,
@@ -243,6 +249,7 @@ public class DefaultComponentStyling(
243249
linkStyle,
244250
menuStyle,
245251
outlinedButtonStyle,
252+
popupAdTextStyle,
246253
popupContainerStyle,
247254
outlinedSplitButtonStyle,
248255
radioButtonStyle,
@@ -285,6 +292,7 @@ public class DefaultComponentStyling(
285292
LocalLinkStyle provides linkStyle,
286293
LocalMenuStyle provides menuStyle,
287294
LocalOutlinedButtonStyle provides outlinedButtonStyle,
295+
LocalPopupAdTextStyle provides popupAdTextStyle,
288296
LocalPopupContainerStyle provides popupContainerStyle,
289297
LocalOutlinedSplitButtonStyle provides outlinedSplitButtonStyle,
290298
LocalRadioButtonStyle provides radioButtonStyle,
@@ -328,6 +336,7 @@ public class DefaultComponentStyling(
328336
if (linkStyle != other.linkStyle) return false
329337
if (menuStyle != other.menuStyle) return false
330338
if (outlinedButtonStyle != other.outlinedButtonStyle) return false
339+
if (popupAdTextStyle != other.popupAdTextStyle) return false
331340
if (popupContainerStyle != other.popupContainerStyle) return false
332341
if (outlinedSplitButtonStyle != other.outlinedSplitButtonStyle) return false
333342
if (radioButtonStyle != other.radioButtonStyle) return false
@@ -368,6 +377,7 @@ public class DefaultComponentStyling(
368377
result = 31 * result + linkStyle.hashCode()
369378
result = 31 * result + menuStyle.hashCode()
370379
result = 31 * result + outlinedButtonStyle.hashCode()
380+
result = 31 * result + popupAdTextStyle.hashCode()
371381
result = 31 * result + popupContainerStyle.hashCode()
372382
result = 31 * result + outlinedSplitButtonStyle.hashCode()
373383
result = 31 * result + radioButtonStyle.hashCode()
@@ -408,6 +418,7 @@ public class DefaultComponentStyling(
408418
"linkStyle=$linkStyle, " +
409419
"menuStyle=$menuStyle, " +
410420
"outlinedButtonStyle=$outlinedButtonStyle, " +
421+
"popupAdTextStyle=$popupAdTextStyle, " +
411422
"popupContainerStyle=$popupContainerStyle, " +
412423
"outlinedSplitButtonStyle=$outlinedSplitButtonStyle, " +
413424
"radioButtonStyle=$radioButtonStyle, " +

0 commit comments

Comments
 (0)