@expo/ui 55.0.7 → 55.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/BadgeView.kt +74 -0
  4. package/android/src/main/java/expo/modules/ui/BadgedBoxView.kt +24 -0
  5. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +21 -0
  6. package/android/src/main/java/expo/modules/ui/SlotView.kt +8 -0
  7. package/android/src/main/java/expo/modules/ui/TooltipView.kt +177 -0
  8. package/build/jetpack-compose/Badge/index.d.ts +31 -0
  9. package/build/jetpack-compose/Badge/index.d.ts.map +1 -0
  10. package/build/jetpack-compose/BadgedBox/index.d.ts +29 -0
  11. package/build/jetpack-compose/BadgedBox/index.d.ts.map +1 -0
  12. package/build/jetpack-compose/Tooltip/index.d.ts +100 -0
  13. package/build/jetpack-compose/Tooltip/index.d.ts.map +1 -0
  14. package/build/jetpack-compose/index.d.ts +3 -0
  15. package/build/jetpack-compose/index.d.ts.map +1 -1
  16. package/expo-module.config.json +1 -1
  17. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.7/expo.modules.ui-55.0.7-sources.jar → 55.0.9/expo.modules.ui-55.0.9-sources.jar} +0 -0
  18. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.md5 +1 -0
  19. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.sha1 +1 -0
  20. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.sha256 +1 -0
  21. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.sha512 +1 -0
  22. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar +0 -0
  23. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.md5 +1 -0
  24. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.sha1 +1 -0
  25. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.sha256 +1 -0
  26. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.sha512 +1 -0
  27. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.7/expo.modules.ui-55.0.7.module → 55.0.9/expo.modules.ui-55.0.9.module} +22 -22
  28. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.md5 +1 -0
  29. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.sha1 +1 -0
  30. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.sha256 +1 -0
  31. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.sha512 +1 -0
  32. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.7/expo.modules.ui-55.0.7.pom → 55.0.9/expo.modules.ui-55.0.9.pom} +1 -1
  33. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.md5 +1 -0
  34. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.sha1 +1 -0
  35. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.sha256 +1 -0
  36. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.sha512 +1 -0
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  42. package/package.json +2 -2
  43. package/src/jetpack-compose/Badge/index.tsx +49 -0
  44. package/src/jetpack-compose/BadgedBox/index.tsx +58 -0
  45. package/src/jetpack-compose/Tooltip/index.tsx +176 -0
  46. package/src/jetpack-compose/index.ts +3 -0
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7-sources.jar.md5 +0 -1
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7-sources.jar.sha1 +0 -1
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7-sources.jar.sha256 +0 -1
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7-sources.jar.sha512 +0 -1
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.aar +0 -0
  52. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.aar.md5 +0 -1
  53. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.aar.sha1 +0 -1
  54. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.aar.sha256 +0 -1
  55. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.aar.sha512 +0 -1
  56. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.module.md5 +0 -1
  57. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.module.sha1 +0 -1
  58. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.module.sha256 +0 -1
  59. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.module.sha512 +0 -1
  60. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.pom.md5 +0 -1
  61. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.pom.sha1 +0 -1
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.pom.sha256 +0 -1
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.7/expo.modules.ui-55.0.7.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -10,6 +10,14 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.9 — 2026-04-06
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 55.0.8 — 2026-04-02
18
+
19
+ _This version does not introduce any user-facing changes._
20
+
13
21
  ## 55.0.7 — 2026-04-02
14
22
 
15
23
  ### 🛠 Breaking changes
@@ -61,6 +69,8 @@
61
69
 
62
70
  ### 🎉 New features
63
71
 
72
+ - [android] Added `TooltipBox`, `PlainTooltip`, and `RichTooltip` components matching native Compose Tooltip API. Supports plain and rich tooltips with slot-based content, programmatic show/dismiss via ref, and `isPersistent`, `hasAction`, `enableUserInput`, `focusable` props. ([#44373](https://github.com/expo/expo/pull/44373) by [@nishan](https://github.com/intergalacticspacehighway))
73
+ - [android] Added `Badge` and `BadgedBox` components wrapping Jetpack Compose's Badge API for status indicators and count overlays. ([#44139](https://github.com/expo/expo/pull/44139) by [@benjaminkomen](https://github.com/benjaminkomen))
64
74
  - [android] Added `shape`, `border`, `selected`, `checked`, `onClick`, and `onCheckedChange` props to `Surface`, supporting clickable, selectable, and toggleable variants. ([#44079](https://github.com/expo/expo/pull/44079) by [@nishan](https://github.com/intergalacticspacehighway))
65
75
  - [android] Added nested text support for Compose `Text` with style inheritance, custom fonts via `expo-font`, `background`, `shadow`, and `lineBreak` properties. ([#44094](https://github.com/expo/expo/pull/44094) by [@nishan](https://github.com/intergalacticspacehighway))
66
76
  - [android] Added `outlined` variant to `TextInput` component. ([#43719](https://github.com/expo/expo/pull/43719) by [@benjaminkomen](https://github.com/benjaminkomen))
@@ -12,13 +12,13 @@ apply plugin: 'expo-module-gradle-plugin'
12
12
  apply plugin: 'org.jetbrains.kotlin.plugin.compose'
13
13
 
14
14
  group = 'expo.modules.ui'
15
- version = '55.0.7'
15
+ version = '55.0.9'
16
16
 
17
17
  android {
18
18
  namespace "expo.modules.ui"
19
19
  defaultConfig {
20
20
  versionCode 1
21
- versionName "55.0.7"
21
+ versionName "55.0.9"
22
22
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
23
23
  }
24
24
  buildFeatures {
@@ -0,0 +1,74 @@
1
+ package expo.modules.ui
2
+
3
+ import android.graphics.Color
4
+ import androidx.compose.foundation.layout.Box
5
+ import androidx.compose.material3.Badge
6
+ import androidx.compose.material3.BadgeDefaults
7
+ import androidx.compose.material3.contentColorFor
8
+ import androidx.compose.runtime.Composable
9
+ import androidx.compose.ui.Alignment
10
+ import androidx.compose.ui.Modifier
11
+ import androidx.compose.ui.layout.layout
12
+ import androidx.compose.ui.unit.dp
13
+ import androidx.core.view.size
14
+ import expo.modules.kotlin.views.ComposableScope
15
+ import expo.modules.kotlin.views.ComposeProps
16
+ import expo.modules.kotlin.views.FunctionalComposableScope
17
+
18
+ data class BadgeProps(
19
+ val containerColor: Color? = null,
20
+ val contentColor: Color? = null,
21
+ val modifiers: ModifierList = emptyList()
22
+ ) : ComposeProps
23
+
24
+ @Composable
25
+ fun FunctionalComposableScope.BadgeContent(props: BadgeProps) {
26
+ val resolvedContainerColor = props.containerColor.composeOrNull ?: BadgeDefaults.containerColor
27
+ val modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)
28
+
29
+ if (view.size > 0) {
30
+ Badge(
31
+ modifier = modifier,
32
+ containerColor = resolvedContainerColor,
33
+ contentColor = props.contentColor.composeOrNull ?: contentColorFor(resolvedContainerColor)
34
+ ) {
35
+ Box(
36
+ modifier = Modifier.ensureBadgeContentCircular(),
37
+ contentAlignment = Alignment.Center
38
+ ) {
39
+ Children(ComposableScope())
40
+ }
41
+ }
42
+ } else {
43
+ // No content lambda → renders as small 6dp dot per M3 spec
44
+ Badge(
45
+ modifier = modifier,
46
+ containerColor = resolvedContainerColor
47
+ )
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Layout modifier that sizes the Badge content so the Badge renders as a circle
53
+ * for narrow content (single digits). Badge internally adds 4dp horizontal padding
54
+ * on each side (8dp total) but no vertical padding. To make the Badge square
55
+ * (and thus circular with CornerFull shape), the content width must be
56
+ * `height - totalHorizontalPadding`. For wide content (e.g. "999+"), the natural
57
+ * width is used, producing a pill shape.
58
+ *
59
+ * This is a workaround for Compose Badge becoming oval at font scales > 1.0.
60
+ * @see: https://issuetracker.google.com/issues/365493087
61
+ */
62
+ private fun Modifier.ensureBadgeContentCircular() = layout { measurable, constraints ->
63
+ val placeable = measurable.measure(constraints)
64
+ // Badge adds 4dp padding on each side = 8dp total horizontal padding
65
+ val targetWidth = placeable.height - BadgeHorizontalPaddingTotal.roundToPx()
66
+ val width = maxOf(placeable.width, targetWidth)
67
+ layout(width, placeable.height) {
68
+ placeable.placeRelative((width - placeable.width) / 2, 0)
69
+ }
70
+ }
71
+
72
+ // Badge internal horizontal padding: 4dp per side = 8dp total
73
+ // (BadgeWithContentHorizontalPadding is internal in Material 3)
74
+ private val BadgeHorizontalPaddingTotal = 8.dp
@@ -0,0 +1,24 @@
1
+ package expo.modules.ui
2
+
3
+ import androidx.compose.material3.Badge
4
+ import androidx.compose.material3.BadgedBox
5
+ import androidx.compose.runtime.Composable
6
+ import expo.modules.kotlin.views.ComposableScope
7
+ import expo.modules.kotlin.views.ComposeProps
8
+ import expo.modules.kotlin.views.FunctionalComposableScope
9
+
10
+ data class BadgedBoxProps(
11
+ val modifiers: ModifierList = emptyList()
12
+ ) : ComposeProps
13
+
14
+ @Composable
15
+ fun FunctionalComposableScope.BadgedBoxContent(props: BadgedBoxProps) {
16
+ val badgeSlot = findChildSlotView(view, "badge")
17
+
18
+ BadgedBox(
19
+ badge = { badgeSlot?.renderSlot() ?: Badge() },
20
+ modifier = ModifierRegistry.applyModifiers(props.modifiers, appContext, composableScope, globalEventDispatcher)
21
+ ) {
22
+ Children(ComposableScope()) { !isSlotView(it) }
23
+ }
24
+ }
@@ -407,6 +407,14 @@ class ExpoUIModule : Module() {
407
407
  ListItemContent(props)
408
408
  }
409
409
 
410
+ ExpoUIView("BadgeView") { props: BadgeProps ->
411
+ BadgeContent(props)
412
+ }
413
+
414
+ ExpoUIView("BadgedBoxView") { props: BadgedBoxProps ->
415
+ BadgedBoxContent(props)
416
+ }
417
+
410
418
  ExpoUIView("SpacerView") { props: SpacerProps ->
411
419
  SpacerContent(props)
412
420
  }
@@ -430,6 +438,19 @@ class ExpoUIModule : Module() {
430
438
  AnimatedVisibilityContent(props)
431
439
  }
432
440
 
441
+ // Class-based views so TooltipBoxView can detect them by type via findChildOfType
442
+ View(PlainTooltipView::class)
443
+ View(RichTooltipView::class)
444
+
445
+ View(TooltipBoxView::class) {
446
+ AsyncFunction("show") Coroutine { view: TooltipBoxView ->
447
+ view.show()
448
+ }
449
+ AsyncFunction("dismiss") Coroutine { view: TooltipBoxView ->
450
+ view.dismiss()
451
+ }
452
+ }
453
+
433
454
  ExpoUIView("RadioButtonView", events = {
434
455
  Events("onButtonPressed")
435
456
  }) { props: RadioButtonProps ->
@@ -59,3 +59,11 @@ fun findChildSlotView(viewGroup: ViewGroup, slotName: String): SlotView? {
59
59
  }
60
60
  return null
61
61
  }
62
+
63
+ inline fun <reified T> findChildOfType(viewGroup: ViewGroup): T? {
64
+ for (index in 0..<viewGroup.size) {
65
+ val child = viewGroup.getChildAt(index)
66
+ if (child is T) return child
67
+ }
68
+ return null
69
+ }
@@ -0,0 +1,177 @@
1
+ @file:OptIn(ExperimentalMaterial3Api::class)
2
+
3
+ package expo.modules.ui
4
+
5
+ import android.annotation.SuppressLint
6
+ import android.content.Context
7
+ import android.graphics.Color
8
+ import androidx.compose.material3.ExperimentalMaterial3Api
9
+ import androidx.compose.material3.PlainTooltip
10
+ import androidx.compose.material3.RichTooltip
11
+ import androidx.compose.material3.TooltipBox
12
+ import androidx.compose.material3.TooltipDefaults
13
+ import androidx.compose.material3.TooltipState
14
+ import androidx.compose.material3.rememberTooltipState
15
+ import androidx.compose.runtime.Composable
16
+ import androidx.compose.runtime.mutableStateOf
17
+ import androidx.compose.runtime.MutableState
18
+ import androidx.compose.runtime.rememberCoroutineScope
19
+ import kotlin.coroutines.cancellation.CancellationException
20
+ import kotlinx.coroutines.CoroutineScope
21
+ import kotlinx.coroutines.withContext
22
+ import expo.modules.kotlin.AppContext
23
+ import expo.modules.kotlin.views.ComposableScope
24
+ import expo.modules.kotlin.views.ComposeProps
25
+ import expo.modules.kotlin.views.ExpoComposeView
26
+
27
+ // --- PlainTooltipView ---
28
+
29
+ data class PlainTooltipViewProps(
30
+ val containerColor: MutableState<Color?> = mutableStateOf(null),
31
+ val contentColor: MutableState<Color?> = mutableStateOf(null),
32
+ val modifiers: MutableState<ModifierList> = mutableStateOf(emptyList())
33
+ ) : ComposeProps
34
+
35
+ @SuppressLint("ViewConstructor")
36
+ class PlainTooltipView(context: Context, appContext: AppContext) :
37
+ ExpoComposeView<PlainTooltipViewProps>(context, appContext) {
38
+ override val props = PlainTooltipViewProps()
39
+
40
+ @Composable
41
+ override fun ComposableScope.Content() {
42
+ Children(this)
43
+ }
44
+ }
45
+
46
+ // --- RichTooltipView ---
47
+
48
+ data class RichTooltipViewProps(
49
+ val containerColor: MutableState<Color?> = mutableStateOf(null),
50
+ val contentColor: MutableState<Color?> = mutableStateOf(null),
51
+ val titleContentColor: MutableState<Color?> = mutableStateOf(null),
52
+ val actionContentColor: MutableState<Color?> = mutableStateOf(null),
53
+ val modifiers: MutableState<ModifierList> = mutableStateOf(emptyList())
54
+ ) : ComposeProps
55
+
56
+ @SuppressLint("ViewConstructor")
57
+ class RichTooltipView(context: Context, appContext: AppContext) :
58
+ ExpoComposeView<RichTooltipViewProps>(context, appContext) {
59
+ override val props = RichTooltipViewProps()
60
+
61
+ @Composable
62
+ override fun ComposableScope.Content() {
63
+ Children(this)
64
+ }
65
+ }
66
+
67
+ // --- TooltipBoxView ---
68
+
69
+ data class TooltipBoxViewProps(
70
+ val isPersistent: MutableState<Boolean> = mutableStateOf(false),
71
+ val hasAction: MutableState<Boolean?> = mutableStateOf(null),
72
+ val enableUserInput: MutableState<Boolean> = mutableStateOf(true),
73
+ val focusable: MutableState<Boolean> = mutableStateOf(false),
74
+ val modifiers: MutableState<ModifierList> = mutableStateOf(emptyList())
75
+ ) : ComposeProps
76
+
77
+ @SuppressLint("ViewConstructor")
78
+ class TooltipBoxView(context: Context, appContext: AppContext) :
79
+ ExpoComposeView<TooltipBoxViewProps>(context, appContext) {
80
+ override val props = TooltipBoxViewProps()
81
+ internal var tooltipState: TooltipState? = null
82
+ private var composeScope: CoroutineScope? = null
83
+
84
+ suspend fun show() {
85
+ val scope = composeScope ?: return
86
+ val state = tooltipState ?: return
87
+ try {
88
+ withContext(scope.coroutineContext) {
89
+ state.show()
90
+ }
91
+ } catch (_: CancellationException) {
92
+ // Can occur if the compose scope is cancelled (view disposed) or if a
93
+ // competing show/dismiss call cancels this one. Safe to ignore in both cases.
94
+ }
95
+ }
96
+
97
+ suspend fun dismiss() {
98
+ val scope = composeScope ?: return
99
+ val state = tooltipState ?: return
100
+ try {
101
+ withContext(scope.coroutineContext) {
102
+ state.dismiss()
103
+ }
104
+ } catch (_: CancellationException) {
105
+ // Can occur if the compose scope is cancelled (view disposed) or if a
106
+ // competing show/dismiss call cancels this one. Safe to ignore in both cases.
107
+ }
108
+ }
109
+
110
+ @Composable
111
+ override fun ComposableScope.Content() {
112
+ val tooltipSlotView = findChildSlotView(this@TooltipBoxView, "tooltip")
113
+ val plainTooltipView = tooltipSlotView?.let { findChildOfType<PlainTooltipView>(it) }
114
+ val richTooltipView = tooltipSlotView?.let { findChildOfType<RichTooltipView>(it) }
115
+
116
+ val tooltipState = rememberTooltipState(isPersistent = props.isPersistent.value)
117
+ val scope = rememberCoroutineScope()
118
+ this@TooltipBoxView.tooltipState = tooltipState
119
+ this@TooltipBoxView.composeScope = scope
120
+
121
+ val actionSlotView = richTooltipView?.let { findChildSlotView(it, "action") }
122
+ val hasAction = props.hasAction.value ?: (actionSlotView != null)
123
+
124
+ val positionProvider = if (richTooltipView != null) {
125
+ TooltipDefaults.rememberRichTooltipPositionProvider()
126
+ } else {
127
+ TooltipDefaults.rememberPlainTooltipPositionProvider()
128
+ }
129
+
130
+ TooltipBox(
131
+ positionProvider = positionProvider,
132
+ enableUserInput = props.enableUserInput.value,
133
+ focusable = props.focusable.value,
134
+ hasAction = hasAction,
135
+ tooltip = {
136
+ if (plainTooltipView != null) {
137
+ PlainTooltip(
138
+ containerColor = plainTooltipView.props.containerColor.value.composeOrNull
139
+ ?: TooltipDefaults.plainTooltipContainerColor,
140
+ contentColor = plainTooltipView.props.contentColor.value.composeOrNull
141
+ ?: TooltipDefaults.plainTooltipContentColor,
142
+ modifier = ModifierRegistry.applyModifiers(plainTooltipView.props.modifiers.value, appContext, this@Content, globalEventDispatcher)
143
+ ) {
144
+ with(ComposableScope()) { with(plainTooltipView) { Content() } }
145
+ }
146
+ } else if (richTooltipView != null) {
147
+ val titleSlotView = findChildSlotView(richTooltipView, "title")
148
+ val textSlotView = findChildSlotView(richTooltipView, "text")
149
+ val defaultColors = TooltipDefaults.richTooltipColors()
150
+
151
+ RichTooltip(
152
+ title = titleSlotView?.let { { it.renderSlot() } },
153
+ action = actionSlotView?.let { { it.renderSlot() } },
154
+ colors = TooltipDefaults.richTooltipColors(
155
+ containerColor = richTooltipView.props.containerColor.value.composeOrNull
156
+ ?: defaultColors.containerColor,
157
+ contentColor = richTooltipView.props.contentColor.value.composeOrNull
158
+ ?: defaultColors.contentColor,
159
+ titleContentColor = richTooltipView.props.titleContentColor.value.composeOrNull
160
+ ?: defaultColors.titleContentColor,
161
+ actionContentColor = richTooltipView.props.actionContentColor.value.composeOrNull
162
+ ?: defaultColors.actionContentColor
163
+ ),
164
+ modifier = ModifierRegistry.applyModifiers(richTooltipView.props.modifiers.value, appContext, this@Content, globalEventDispatcher)
165
+ ) {
166
+ textSlotView?.renderSlot()
167
+ }
168
+ }
169
+ },
170
+ state = tooltipState,
171
+ modifier = ModifierRegistry.applyModifiers(props.modifiers.value, appContext, this@Content, globalEventDispatcher)
172
+ ) {
173
+ Children(ComposableScope(), filter = { !isSlotView(it) })
174
+ }
175
+ }
176
+ }
177
+
@@ -0,0 +1,31 @@
1
+ import { type ColorValue } from 'react-native';
2
+ import { type ModifierConfig } from '../../types';
3
+ export type BadgeProps = {
4
+ /**
5
+ * Background color of the badge.
6
+ * @default BadgeDefaults.containerColor
7
+ */
8
+ containerColor?: ColorValue;
9
+ /**
10
+ * Content color inside the badge (text/icon tint).
11
+ * @default BadgeDefaults.contentColor
12
+ */
13
+ contentColor?: ColorValue;
14
+ /**
15
+ * Modifiers for the component.
16
+ */
17
+ modifiers?: ModifierConfig[];
18
+ /**
19
+ * Optional content inside the badge (for example, a `Text` with a count).
20
+ * When omitted, renders as a small indicator dot.
21
+ */
22
+ children?: React.ReactNode;
23
+ };
24
+ /**
25
+ * A badge component matching Compose's `Badge`.
26
+ * Renders as a small colored indicator dot, or with content (for example, a count).
27
+ *
28
+ * @see [Jetpack Compose Badge](https://developer.android.com/develop/ui/compose/components/badges)
29
+ */
30
+ export declare function Badge(props: BadgeProps): import("react").JSX.Element;
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jetpack-compose/Badge/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,MAAM,UAAU,GAAG;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B;;;OAGG;IACH,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B;;OAEG;IACH,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAaF;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,+BAGtC"}
@@ -0,0 +1,29 @@
1
+ import { type ModifierConfig } from '../../types';
2
+ export type BadgedBoxProps = {
3
+ /**
4
+ * Modifiers for the component.
5
+ */
6
+ modifiers?: ModifierConfig[];
7
+ /**
8
+ * Children containing the main content and a `BadgedBox.Badge` slot.
9
+ */
10
+ children?: React.ReactNode;
11
+ };
12
+ /**
13
+ * Slot for the badge overlay. Place a `Badge` component inside.
14
+ */
15
+ declare function BadgeSlot(props: {
16
+ children: React.ReactNode;
17
+ }): import("react").JSX.Element;
18
+ /**
19
+ * A badged box matching Compose's `BadgedBox`.
20
+ * Overlays a badge on top of content (for example, an icon).
21
+ *
22
+ * @see [Jetpack Compose BadgedBox](https://developer.android.com/develop/ui/compose/components/badges)
23
+ */
24
+ declare function BadgedBoxComponent(props: BadgedBoxProps): import("react").JSX.Element;
25
+ declare namespace BadgedBoxComponent {
26
+ var Badge: typeof BadgeSlot;
27
+ }
28
+ export { BadgedBoxComponent as BadgedBox };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jetpack-compose/BadgedBox/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAuBF;;GAEG;AACH,iBAAS,SAAS,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,+BAEtD;AAED;;;;;GAKG;AACH,iBAAS,kBAAkB,CAAC,KAAK,EAAE,cAAc,+BAGhD;kBAHQ,kBAAkB;;;AAO3B,OAAO,EAAE,kBAAkB,IAAI,SAAS,EAAE,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { type Ref } from 'react';
2
+ import { type ColorValue } from 'react-native';
3
+ import { type ModifierConfig } from '../../types';
4
+ export type TooltipBoxRef = {
5
+ /**
6
+ * Programmatically shows the tooltip.
7
+ */
8
+ show: () => Promise<void>;
9
+ /**
10
+ * Programmatically dismisses the tooltip.
11
+ */
12
+ dismiss: () => Promise<void>;
13
+ };
14
+ export type TooltipBoxProps = {
15
+ /**
16
+ * Ref to imperatively show/dismiss the tooltip.
17
+ */
18
+ ref?: Ref<TooltipBoxRef>;
19
+ /**
20
+ * Whether the tooltip persists instead of auto-dismissing after a short timeout.
21
+ * @default false
22
+ */
23
+ isPersistent?: boolean;
24
+ /**
25
+ * Whether the tooltip contains an action. Affects accessibility and dismiss behavior.
26
+ * When not specified, this is automatically derived from the presence of a `RichTooltip.Action` slot.
27
+ */
28
+ hasAction?: boolean;
29
+ /**
30
+ * Whether user input (long-press, hover) triggers the tooltip.
31
+ * @default true
32
+ */
33
+ enableUserInput?: boolean;
34
+ /**
35
+ * Whether the tooltip popup is focusable.
36
+ * @default false
37
+ */
38
+ focusable?: boolean;
39
+ /**
40
+ * Modifiers for the component.
41
+ */
42
+ modifiers?: ModifierConfig[];
43
+ /**
44
+ * Children containing a `TooltipBox.PlainTooltip` or `TooltipBox.RichTooltip` slot and the anchor/trigger content.
45
+ * The anchor content triggers the tooltip on long-press.
46
+ */
47
+ children: React.ReactNode;
48
+ };
49
+ export type PlainTooltipProps = {
50
+ containerColor?: ColorValue;
51
+ contentColor?: ColorValue;
52
+ modifiers?: ModifierConfig[];
53
+ children: React.ReactNode;
54
+ };
55
+ /**
56
+ * A simple tooltip. Place inside `TooltipBox` as `TooltipBox.PlainTooltip`.
57
+ * Children become the tooltip content.
58
+ */
59
+ declare function PlainTooltipComponent(props: PlainTooltipProps): import("react").JSX.Element;
60
+ export type RichTooltipProps = {
61
+ containerColor?: ColorValue;
62
+ contentColor?: ColorValue;
63
+ titleContentColor?: ColorValue;
64
+ actionContentColor?: ColorValue;
65
+ modifiers?: ModifierConfig[];
66
+ children: React.ReactNode;
67
+ };
68
+ declare function RichTooltipTitle(props: {
69
+ children: React.ReactNode;
70
+ }): import("react").JSX.Element;
71
+ declare function RichTooltipText(props: {
72
+ children: React.ReactNode;
73
+ }): import("react").JSX.Element;
74
+ declare function RichTooltipAction(props: {
75
+ children: React.ReactNode;
76
+ }): import("react").JSX.Element;
77
+ /**
78
+ * A detailed tooltip with optional title, body text, and action. Place inside `TooltipBox` as `TooltipBox.RichTooltip`.
79
+ * Content is provided via sub-components: `TooltipBox.RichTooltip.Title`, `TooltipBox.RichTooltip.Text`, `TooltipBox.RichTooltip.Action`.
80
+ */
81
+ declare function RichTooltipComponent(props: RichTooltipProps): import("react").JSX.Element;
82
+ declare namespace RichTooltipComponent {
83
+ var Title: typeof RichTooltipTitle;
84
+ var Text: typeof RichTooltipText;
85
+ var Action: typeof RichTooltipAction;
86
+ }
87
+ /**
88
+ * A container that wraps anchor content and shows a tooltip on long-press.
89
+ * Provide the tooltip content via `TooltipBox.PlainTooltip` or `TooltipBox.RichTooltip`.
90
+ * All other children are the anchor/trigger.
91
+ *
92
+ * Use `ref` to imperatively `show()` or `dismiss()` the tooltip.
93
+ */
94
+ declare function TooltipBoxComponent(props: TooltipBoxProps): import("react").JSX.Element;
95
+ declare namespace TooltipBoxComponent {
96
+ var PlainTooltip: typeof PlainTooltipComponent;
97
+ var RichTooltip: typeof RichTooltipComponent;
98
+ }
99
+ export { TooltipBoxComponent as TooltipBox };
100
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jetpack-compose/Tooltip/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,MAAM,aAAa,GAAG;IAC1B;;OAEG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B;;OAEG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B;;OAEG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AA0BF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAOF;;;GAGG;AACH,iBAAS,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,+BAYtD;AAID,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,kBAAkB,CAAC,EAAE,UAAU,CAAC;IAChC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAOF,iBAAS,gBAAgB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,+BAE7D;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,+BAE5D;AAED,iBAAS,iBAAiB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,+BAE9D;AAED;;;GAGG;AACH,iBAAS,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,+BAYpD;kBAZQ,oBAAoB;;;;;AAoB7B;;;;;;GAMG;AACH,iBAAS,mBAAmB,CAAC,KAAK,EAAE,eAAe,+BAGlD;kBAHQ,mBAAmB;;;;AAQ5B,OAAO,EAAE,mBAAmB,IAAI,UAAU,EAAE,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import './MaterialSymbolsAssetsTransformer.fx';
2
2
  export * from './AlertDialog';
3
+ export * from './Badge';
4
+ export * from './BadgedBox';
3
5
  export { BasicAlertDialog, type BasicAlertDialogProps } from './BasicAlertDialog';
4
6
  export * from './Card';
5
7
  export * from './Checkbox';
@@ -32,6 +34,7 @@ export * from './PullToRefreshBox';
32
34
  export * from './RadioButton';
33
35
  export * from './Surface';
34
36
  export { type TextProps, Text } from './Text';
37
+ export * from './Tooltip';
35
38
  export * from './AnimatedVisibility';
36
39
  export * from './Box';
37
40
  export * from './Row';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jetpack-compose/index.ts"],"names":[],"mappings":"AAAA,OAAO,uCAAuC,CAAC;AAE/C,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAClF,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,KAAK,SAAS,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jetpack-compose/index.ts"],"names":[],"mappings":"AAAA,OAAO,uCAAuC,CAAC;AAE/C,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAClF,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,KAAK,SAAS,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9C,cAAc,WAAW,CAAC;AAE1B,cAAc,sBAAsB,CAAC;AACrC,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
@@ -10,7 +10,7 @@
10
10
  "publication": {
11
11
  "groupId": "expo.modules.ui",
12
12
  "artifactId": "expo.modules.ui",
13
- "version": "55.0.7",
13
+ "version": "55.0.9",
14
14
  "repository": "local-maven-repo"
15
15
  }
16
16
  }
@@ -0,0 +1 @@
1
+ 0fb41718cf502bf1bd5bfeefef2497a791ec4067
@@ -0,0 +1 @@
1
+ 6f17f489b1f61bda39b7219a16731839a2436678e8e1258f862b6f126229a160
@@ -0,0 +1 @@
1
+ d9c690394b14a26e66a9e2520000d48ab9d98163b4495ff3acf0be27d3c285e3f3c11a4e9843c124d9bbf1d8da51064956af5f3fd7f11e4775ef5d6d32a2487b
@@ -0,0 +1 @@
1
+ 47a9ad9a4255f9c8a380708a52ffe51ccba93762
@@ -0,0 +1 @@
1
+ 0cc100bb063457e6e0be298e51fd87edbe497d86fcf01f7f4e32b83ba71ee443
@@ -0,0 +1 @@
1
+ 6eabbcc0f2c5ca30426dc5325e8d02ee5cd43c5c2d3660996b29d5344b609532e4cc79251162be6974dcc54c5722c50b54d59ce0ea8b422db6c1efb5a460c830
@@ -3,7 +3,7 @@
3
3
  "component": {
4
4
  "group": "expo.modules.ui",
5
5
  "module": "expo.modules.ui",
6
- "version": "55.0.7",
6
+ "version": "55.0.9",
7
7
  "attributes": {
8
8
  "org.gradle.status": "release"
9
9
  }
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "files": [
26
26
  {
27
- "name": "expo.modules.ui-55.0.7.aar",
28
- "url": "expo.modules.ui-55.0.7.aar",
29
- "size": 984275,
30
- "sha512": "fc12d4f1223dc477347edf00a0ac9884ec8c05935e172588b7a02b4862a2ffaf349bfb3e41e945a60fc426660f421ccffe254bf0f4746503a9a621182aede9b7",
31
- "sha256": "f73a8257262c66e8ca0af6247db6e20b17a895d6e88cec7861c967d4336c4e71",
32
- "sha1": "aef8c546077f395d701e22459b9557564b60fca0",
33
- "md5": "6f7ed7560ebf12a44e7ab271ea245771"
27
+ "name": "expo.modules.ui-55.0.9.aar",
28
+ "url": "expo.modules.ui-55.0.9.aar",
29
+ "size": 1048460,
30
+ "sha512": "6eabbcc0f2c5ca30426dc5325e8d02ee5cd43c5c2d3660996b29d5344b609532e4cc79251162be6974dcc54c5722c50b54d59ce0ea8b422db6c1efb5a460c830",
31
+ "sha256": "0cc100bb063457e6e0be298e51fd87edbe497d86fcf01f7f4e32b83ba71ee443",
32
+ "sha1": "47a9ad9a4255f9c8a380708a52ffe51ccba93762",
33
+ "md5": "476bb1e92103b2fde36a36bb0b3af37e"
34
34
  }
35
35
  ]
36
36
  },
@@ -120,13 +120,13 @@
120
120
  ],
121
121
  "files": [
122
122
  {
123
- "name": "expo.modules.ui-55.0.7.aar",
124
- "url": "expo.modules.ui-55.0.7.aar",
125
- "size": 984275,
126
- "sha512": "fc12d4f1223dc477347edf00a0ac9884ec8c05935e172588b7a02b4862a2ffaf349bfb3e41e945a60fc426660f421ccffe254bf0f4746503a9a621182aede9b7",
127
- "sha256": "f73a8257262c66e8ca0af6247db6e20b17a895d6e88cec7861c967d4336c4e71",
128
- "sha1": "aef8c546077f395d701e22459b9557564b60fca0",
129
- "md5": "6f7ed7560ebf12a44e7ab271ea245771"
123
+ "name": "expo.modules.ui-55.0.9.aar",
124
+ "url": "expo.modules.ui-55.0.9.aar",
125
+ "size": 1048460,
126
+ "sha512": "6eabbcc0f2c5ca30426dc5325e8d02ee5cd43c5c2d3660996b29d5344b609532e4cc79251162be6974dcc54c5722c50b54d59ce0ea8b422db6c1efb5a460c830",
127
+ "sha256": "0cc100bb063457e6e0be298e51fd87edbe497d86fcf01f7f4e32b83ba71ee443",
128
+ "sha1": "47a9ad9a4255f9c8a380708a52ffe51ccba93762",
129
+ "md5": "476bb1e92103b2fde36a36bb0b3af37e"
130
130
  }
131
131
  ]
132
132
  },
@@ -140,13 +140,13 @@
140
140
  },
141
141
  "files": [
142
142
  {
143
- "name": "expo.modules.ui-55.0.7-sources.jar",
144
- "url": "expo.modules.ui-55.0.7-sources.jar",
145
- "size": 63052,
146
- "sha512": "1498e7baba58e8b17988e3f84b24561032849f1a353da509c8bafcd50abe67027889e2e54b2e5473fa055fbf08dc9cf9b728c3c108e16fc8b9bc20bde019039a",
147
- "sha256": "2b50b26af7df4c5211dcb3fb2e0bcbc1e67b9d7643be03944ebdc2ff624283d7",
148
- "sha1": "b2262e6bc6fdbba4542a361ca47cc99466fff958",
149
- "md5": "8d71e6eff7e8a861b9877b89a6dd84c6"
143
+ "name": "expo.modules.ui-55.0.9-sources.jar",
144
+ "url": "expo.modules.ui-55.0.9-sources.jar",
145
+ "size": 66487,
146
+ "sha512": "d9c690394b14a26e66a9e2520000d48ab9d98163b4495ff3acf0be27d3c285e3f3c11a4e9843c124d9bbf1d8da51064956af5f3fd7f11e4775ef5d6d32a2487b",
147
+ "sha256": "6f17f489b1f61bda39b7219a16731839a2436678e8e1258f862b6f126229a160",
148
+ "sha1": "0fb41718cf502bf1bd5bfeefef2497a791ec4067",
149
+ "md5": "1f6068b64a52c28e06da5f7a2d25f96c"
150
150
  }
151
151
  ]
152
152
  }
@@ -0,0 +1 @@
1
+ 306436c3ff7f3c30b53ee8b940945dabbc36b24d
@@ -0,0 +1 @@
1
+ b8df9570f0f933ef85bb704ff46e2cbc9dc22892920f4e0adb47b986365f9b3f
@@ -0,0 +1 @@
1
+ c8d4a472bf73c83cae71aa7db7153a20c0a13aac6301c5755c0564e5ee24ea4032ba731a5f413e012476378fc5bcc9b911dbcd8e08c78e4b5e07a34227ed18af
@@ -9,7 +9,7 @@
9
9
  <modelVersion>4.0.0</modelVersion>
10
10
  <groupId>expo.modules.ui</groupId>
11
11
  <artifactId>expo.modules.ui</artifactId>
12
- <version>55.0.7</version>
12
+ <version>55.0.9</version>
13
13
  <packaging>aar</packaging>
14
14
  <name>expo.modules.ui</name>
15
15
  <url>https://github.com/expo/expo</url>
@@ -0,0 +1 @@
1
+ 1d3a9a8f13d6441cda844651c174746d39b381be
@@ -0,0 +1 @@
1
+ 527c9694e0973613a33f52492c60646d29299008884ac08ac7bccfec640286dd
@@ -0,0 +1 @@
1
+ 250fc082bf23c5d924a4df3ceb01525ce618d9ac449c6ed6140fde52215afbda4ab114fa249ba0b24de739942e810567f69adbf412d57e1423480c4c865cc8a7
@@ -3,11 +3,11 @@
3
3
  <groupId>expo.modules.ui</groupId>
4
4
  <artifactId>expo.modules.ui</artifactId>
5
5
  <versioning>
6
- <latest>55.0.7</latest>
7
- <release>55.0.7</release>
6
+ <latest>55.0.9</latest>
7
+ <release>55.0.9</release>
8
8
  <versions>
9
- <version>55.0.7</version>
9
+ <version>55.0.9</version>
10
10
  </versions>
11
- <lastUpdated>20260402182216</lastUpdated>
11
+ <lastUpdated>20260406145353</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -1 +1 @@
1
- e2fa3e793abf2396f70b183a586d7d6f
1
+ 512c30401c335ddaa5c8a143422f5f3f
@@ -1 +1 @@
1
- 118b63f6f7f61a2c3594ea824f9139ca405968db
1
+ bffac0e03358cb495aff9195a3bf93ad3d004c4b
@@ -1 +1 @@
1
- 3dea49a5d731454d64728f51a5765239882c6bc7d81a84a0a863dbc7a9d069dc
1
+ 7ce3b849501b2897111d27627b715a85b21f39a0a9c3f3005d4429af92279f60
@@ -1 +1 @@
1
- 53369821dfeef9c170ebb34662f23d6d4d3f48458e0c02f54a1ad1675877d110413bd95e590263b2fe639aec09d9eba31e88ffbe399be1817b6768debab1670d
1
+ 3e96702666bb6d88dfbed286974dd194a9ea50aa55de5f9a2ec267383b0c3ef556e5984ac83c5d83ca951f35f07ecc19382fdd0eefe110f8d94a64b5a62f7264
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "55.0.7",
3
+ "version": "55.0.9",
4
4
  "description": "A collection of UI components",
5
5
  "sideEffects": [
6
6
  "*.fx.js"
@@ -67,5 +67,5 @@
67
67
  "react": "*",
68
68
  "react-native": "*"
69
69
  },
70
- "gitHead": "d455edeea68e2a27ab9a4d5143bdfaf6851f852c"
70
+ "gitHead": "9cfae0185951ef0eb335e1c1270c7682ff761f69"
71
71
  }
@@ -0,0 +1,49 @@
1
+ import { requireNativeView } from 'expo';
2
+ import { type ColorValue } from 'react-native';
3
+
4
+ import { type ModifierConfig } from '../../types';
5
+ import { createViewModifierEventListener } from '../modifiers/utils';
6
+
7
+ export type BadgeProps = {
8
+ /**
9
+ * Background color of the badge.
10
+ * @default BadgeDefaults.containerColor
11
+ */
12
+ containerColor?: ColorValue;
13
+ /**
14
+ * Content color inside the badge (text/icon tint).
15
+ * @default BadgeDefaults.contentColor
16
+ */
17
+ contentColor?: ColorValue;
18
+ /**
19
+ * Modifiers for the component.
20
+ */
21
+ modifiers?: ModifierConfig[];
22
+ /**
23
+ * Optional content inside the badge (for example, a `Text` with a count).
24
+ * When omitted, renders as a small indicator dot.
25
+ */
26
+ children?: React.ReactNode;
27
+ };
28
+
29
+ const BadgeNativeView: React.ComponentType<BadgeProps> = requireNativeView('ExpoUI', 'BadgeView');
30
+
31
+ function transformProps(props: BadgeProps): BadgeProps {
32
+ const { modifiers, ...restProps } = props;
33
+ return {
34
+ modifiers,
35
+ ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
36
+ ...restProps,
37
+ };
38
+ }
39
+
40
+ /**
41
+ * A badge component matching Compose's `Badge`.
42
+ * Renders as a small colored indicator dot, or with content (for example, a count).
43
+ *
44
+ * @see [Jetpack Compose Badge](https://developer.android.com/develop/ui/compose/components/badges)
45
+ */
46
+ export function Badge(props: BadgeProps) {
47
+ const { children, ...restProps } = props;
48
+ return <BadgeNativeView {...transformProps(restProps)}>{children}</BadgeNativeView>;
49
+ }
@@ -0,0 +1,58 @@
1
+ import { requireNativeView } from 'expo';
2
+
3
+ import { type ModifierConfig } from '../../types';
4
+ import { createViewModifierEventListener } from '../modifiers/utils';
5
+
6
+ export type BadgedBoxProps = {
7
+ /**
8
+ * Modifiers for the component.
9
+ */
10
+ modifiers?: ModifierConfig[];
11
+ /**
12
+ * Children containing the main content and a `BadgedBox.Badge` slot.
13
+ */
14
+ children?: React.ReactNode;
15
+ };
16
+
17
+ type SlotProps = {
18
+ slotName: string;
19
+ children: React.ReactNode;
20
+ };
21
+
22
+ const BadgedBoxNativeView: React.ComponentType<BadgedBoxProps> = requireNativeView(
23
+ 'ExpoUI',
24
+ 'BadgedBoxView'
25
+ );
26
+
27
+ const SlotNativeView: React.ComponentType<SlotProps> = requireNativeView('ExpoUI', 'SlotView');
28
+
29
+ function transformProps(props: BadgedBoxProps): BadgedBoxProps {
30
+ const { modifiers, ...restProps } = props;
31
+ return {
32
+ modifiers,
33
+ ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
34
+ ...restProps,
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Slot for the badge overlay. Place a `Badge` component inside.
40
+ */
41
+ function BadgeSlot(props: { children: React.ReactNode }) {
42
+ return <SlotNativeView slotName="badge">{props.children}</SlotNativeView>;
43
+ }
44
+
45
+ /**
46
+ * A badged box matching Compose's `BadgedBox`.
47
+ * Overlays a badge on top of content (for example, an icon).
48
+ *
49
+ * @see [Jetpack Compose BadgedBox](https://developer.android.com/develop/ui/compose/components/badges)
50
+ */
51
+ function BadgedBoxComponent(props: BadgedBoxProps) {
52
+ const { children, ...restProps } = props;
53
+ return <BadgedBoxNativeView {...transformProps(restProps)}>{children}</BadgedBoxNativeView>;
54
+ }
55
+
56
+ BadgedBoxComponent.Badge = BadgeSlot;
57
+
58
+ export { BadgedBoxComponent as BadgedBox };
@@ -0,0 +1,176 @@
1
+ import { requireNativeView } from 'expo';
2
+ import { type Ref } from 'react';
3
+ import { type ColorValue } from 'react-native';
4
+
5
+ import { type ModifierConfig } from '../../types';
6
+ import { createViewModifierEventListener } from '../modifiers/utils';
7
+
8
+ export type TooltipBoxRef = {
9
+ /**
10
+ * Programmatically shows the tooltip.
11
+ */
12
+ show: () => Promise<void>;
13
+ /**
14
+ * Programmatically dismisses the tooltip.
15
+ */
16
+ dismiss: () => Promise<void>;
17
+ };
18
+
19
+ export type TooltipBoxProps = {
20
+ /**
21
+ * Ref to imperatively show/dismiss the tooltip.
22
+ */
23
+ ref?: Ref<TooltipBoxRef>;
24
+ /**
25
+ * Whether the tooltip persists instead of auto-dismissing after a short timeout.
26
+ * @default false
27
+ */
28
+ isPersistent?: boolean;
29
+ /**
30
+ * Whether the tooltip contains an action. Affects accessibility and dismiss behavior.
31
+ * When not specified, this is automatically derived from the presence of a `RichTooltip.Action` slot.
32
+ */
33
+ hasAction?: boolean;
34
+ /**
35
+ * Whether user input (long-press, hover) triggers the tooltip.
36
+ * @default true
37
+ */
38
+ enableUserInput?: boolean;
39
+ /**
40
+ * Whether the tooltip popup is focusable.
41
+ * @default false
42
+ */
43
+ focusable?: boolean;
44
+ /**
45
+ * Modifiers for the component.
46
+ */
47
+ modifiers?: ModifierConfig[];
48
+ /**
49
+ * Children containing a `TooltipBox.PlainTooltip` or `TooltipBox.RichTooltip` slot and the anchor/trigger content.
50
+ * The anchor content triggers the tooltip on long-press.
51
+ */
52
+ children: React.ReactNode;
53
+ };
54
+
55
+ const TooltipBoxNativeView: React.ComponentType<TooltipBoxProps> = requireNativeView(
56
+ 'ExpoUI',
57
+ 'TooltipBoxView'
58
+ );
59
+
60
+ const SlotNativeView: React.ComponentType<{ slotName: string; children: React.ReactNode }> =
61
+ requireNativeView('ExpoUI', 'SlotView');
62
+
63
+ function transformProps(
64
+ props: Omit<TooltipBoxProps, 'children'>
65
+ ): Omit<TooltipBoxProps, 'children'> {
66
+ const { modifiers, ...restProps } = props;
67
+ return {
68
+ modifiers,
69
+ ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
70
+ ...restProps,
71
+ isPersistent: props.isPersistent ?? false,
72
+ enableUserInput: props.enableUserInput ?? true,
73
+ focusable: props.focusable ?? false,
74
+ };
75
+ }
76
+
77
+ // --- PlainTooltip (compound component of TooltipBox) ---
78
+
79
+ export type PlainTooltipProps = {
80
+ containerColor?: ColorValue;
81
+ contentColor?: ColorValue;
82
+ modifiers?: ModifierConfig[];
83
+ children: React.ReactNode;
84
+ };
85
+
86
+ const PlainTooltipNativeView: React.ComponentType<PlainTooltipProps> = requireNativeView(
87
+ 'ExpoUI',
88
+ 'PlainTooltipView'
89
+ );
90
+
91
+ /**
92
+ * A simple tooltip. Place inside `TooltipBox` as `TooltipBox.PlainTooltip`.
93
+ * Children become the tooltip content.
94
+ */
95
+ function PlainTooltipComponent(props: PlainTooltipProps) {
96
+ const { children, modifiers, ...restProps } = props;
97
+ return (
98
+ <SlotNativeView slotName="tooltip">
99
+ <PlainTooltipNativeView
100
+ modifiers={modifiers}
101
+ {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
102
+ {...restProps}>
103
+ {children}
104
+ </PlainTooltipNativeView>
105
+ </SlotNativeView>
106
+ );
107
+ }
108
+
109
+ // --- RichTooltip (compound component of TooltipBox) ---
110
+
111
+ export type RichTooltipProps = {
112
+ containerColor?: ColorValue;
113
+ contentColor?: ColorValue;
114
+ titleContentColor?: ColorValue;
115
+ actionContentColor?: ColorValue;
116
+ modifiers?: ModifierConfig[];
117
+ children: React.ReactNode;
118
+ };
119
+
120
+ const RichTooltipNativeView: React.ComponentType<RichTooltipProps> = requireNativeView(
121
+ 'ExpoUI',
122
+ 'RichTooltipView'
123
+ );
124
+
125
+ function RichTooltipTitle(props: { children: React.ReactNode }) {
126
+ return <SlotNativeView slotName="title">{props.children}</SlotNativeView>;
127
+ }
128
+
129
+ function RichTooltipText(props: { children: React.ReactNode }) {
130
+ return <SlotNativeView slotName="text">{props.children}</SlotNativeView>;
131
+ }
132
+
133
+ function RichTooltipAction(props: { children: React.ReactNode }) {
134
+ return <SlotNativeView slotName="action">{props.children}</SlotNativeView>;
135
+ }
136
+
137
+ /**
138
+ * A detailed tooltip with optional title, body text, and action. Place inside `TooltipBox` as `TooltipBox.RichTooltip`.
139
+ * Content is provided via sub-components: `TooltipBox.RichTooltip.Title`, `TooltipBox.RichTooltip.Text`, `TooltipBox.RichTooltip.Action`.
140
+ */
141
+ function RichTooltipComponent(props: RichTooltipProps) {
142
+ const { children, modifiers, ...restProps } = props;
143
+ return (
144
+ <SlotNativeView slotName="tooltip">
145
+ <RichTooltipNativeView
146
+ modifiers={modifiers}
147
+ {...(modifiers ? createViewModifierEventListener(modifiers) : undefined)}
148
+ {...restProps}>
149
+ {children}
150
+ </RichTooltipNativeView>
151
+ </SlotNativeView>
152
+ );
153
+ }
154
+
155
+ RichTooltipComponent.Title = RichTooltipTitle;
156
+ RichTooltipComponent.Text = RichTooltipText;
157
+ RichTooltipComponent.Action = RichTooltipAction;
158
+
159
+ // --- TooltipBox ---
160
+
161
+ /**
162
+ * A container that wraps anchor content and shows a tooltip on long-press.
163
+ * Provide the tooltip content via `TooltipBox.PlainTooltip` or `TooltipBox.RichTooltip`.
164
+ * All other children are the anchor/trigger.
165
+ *
166
+ * Use `ref` to imperatively `show()` or `dismiss()` the tooltip.
167
+ */
168
+ function TooltipBoxComponent(props: TooltipBoxProps) {
169
+ const { children, ...restProps } = props;
170
+ return <TooltipBoxNativeView {...transformProps(restProps)}>{children}</TooltipBoxNativeView>;
171
+ }
172
+
173
+ TooltipBoxComponent.PlainTooltip = PlainTooltipComponent;
174
+ TooltipBoxComponent.RichTooltip = RichTooltipComponent;
175
+
176
+ export { TooltipBoxComponent as TooltipBox };
@@ -1,6 +1,8 @@
1
1
  import './MaterialSymbolsAssetsTransformer.fx';
2
2
 
3
3
  export * from './AlertDialog';
4
+ export * from './Badge';
5
+ export * from './BadgedBox';
4
6
  export { BasicAlertDialog, type BasicAlertDialogProps } from './BasicAlertDialog';
5
7
  export * from './Card';
6
8
  export * from './Checkbox';
@@ -33,6 +35,7 @@ export * from './PullToRefreshBox';
33
35
  export * from './RadioButton';
34
36
  export * from './Surface';
35
37
  export { type TextProps, Text } from './Text';
38
+ export * from './Tooltip';
36
39
 
37
40
  export * from './AnimatedVisibility';
38
41
  export * from './Box';
@@ -1 +0,0 @@
1
- b2262e6bc6fdbba4542a361ca47cc99466fff958
@@ -1 +0,0 @@
1
- 2b50b26af7df4c5211dcb3fb2e0bcbc1e67b9d7643be03944ebdc2ff624283d7
@@ -1 +0,0 @@
1
- 1498e7baba58e8b17988e3f84b24561032849f1a353da509c8bafcd50abe67027889e2e54b2e5473fa055fbf08dc9cf9b728c3c108e16fc8b9bc20bde019039a
@@ -1 +0,0 @@
1
- 6f7ed7560ebf12a44e7ab271ea245771
@@ -1 +0,0 @@
1
- aef8c546077f395d701e22459b9557564b60fca0
@@ -1 +0,0 @@
1
- f73a8257262c66e8ca0af6247db6e20b17a895d6e88cec7861c967d4336c4e71
@@ -1 +0,0 @@
1
- fc12d4f1223dc477347edf00a0ac9884ec8c05935e172588b7a02b4862a2ffaf349bfb3e41e945a60fc426660f421ccffe254bf0f4746503a9a621182aede9b7
@@ -1 +0,0 @@
1
- a1d79421dc618d4c0804b992f62c4c4503e3138f
@@ -1 +0,0 @@
1
- 7311eb6bdd704c64c17b3c503ffd205be5e944dee89a1107abb048b22372fb40
@@ -1 +0,0 @@
1
- 69a516af8b457a7d7f0d5f9138fba7b756f647f830bd3d9b70e4977fd1247e45d6a2f1ab3f2b0bb7cf6c3678091636a204370fe8f504a0f038f4415e4743eb60
@@ -1 +0,0 @@
1
- f86c7537a50c62f42e8a961ba0c1b22d
@@ -1 +0,0 @@
1
- 89a6aa0c91094496af60e95d8d8b1def7ed014b0
@@ -1 +0,0 @@
1
- 1869a810c915ea81553e7eda54c0266f15679cce9d4816a94c999a8cb012664c
@@ -1 +0,0 @@
1
- 3b045ee212e24d32ac965e826ae4c61b50a1468a42d31bd322dd91b3a2c4745d2344923b1bf83e2541d62fc1f9aa187c385f46318b01f778ef70a757e5dc9b47