Merge "Revert "Move tooltip implementation to common"" into androidx-main
diff --git a/compose/material3/material3/api/1.3.0-beta01.txt b/compose/material3/material3/api/1.3.0-beta01.txt
index f92b5a9..40db5a9 100644
--- a/compose/material3/material3/api/1.3.0-beta01.txt
+++ b/compose/material3/material3/api/1.3.0-beta01.txt
@@ -2012,8 +2012,6 @@
}
public final class TooltipKt {
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TooltipBox(androidx.compose.ui.window.PopupPositionProvider positionProvider, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipScope,kotlin.Unit> tooltip, androidx.compose.material3.TooltipState state, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional boolean enableUserInput, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.TooltipState TooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TooltipState rememberTooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
@@ -2035,6 +2033,11 @@
property public abstract androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> transition;
}
+ public final class Tooltip_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+ }
+
@SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
method public androidx.compose.material3.TopAppBarColors copy(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index f92b5a9..40db5a9 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -2012,8 +2012,6 @@
}
public final class TooltipKt {
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TooltipBox(androidx.compose.ui.window.PopupPositionProvider positionProvider, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipScope,kotlin.Unit> tooltip, androidx.compose.material3.TooltipState state, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional boolean enableUserInput, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.TooltipState TooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TooltipState rememberTooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
@@ -2035,6 +2033,11 @@
property public abstract androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> transition;
}
+ public final class Tooltip_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+ }
+
@SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
method public androidx.compose.material3.TopAppBarColors copy(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
diff --git a/compose/material3/material3/api/restricted_1.3.0-beta01.txt b/compose/material3/material3/api/restricted_1.3.0-beta01.txt
index f92b5a9..40db5a9 100644
--- a/compose/material3/material3/api/restricted_1.3.0-beta01.txt
+++ b/compose/material3/material3/api/restricted_1.3.0-beta01.txt
@@ -2012,8 +2012,6 @@
}
public final class TooltipKt {
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TooltipBox(androidx.compose.ui.window.PopupPositionProvider positionProvider, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipScope,kotlin.Unit> tooltip, androidx.compose.material3.TooltipState state, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional boolean enableUserInput, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.TooltipState TooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TooltipState rememberTooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
@@ -2035,6 +2033,11 @@
property public abstract androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> transition;
}
+ public final class Tooltip_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+ }
+
@SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
method public androidx.compose.material3.TopAppBarColors copy(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index f92b5a9..40db5a9 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -2012,8 +2012,6 @@
}
public final class TooltipKt {
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
- method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void TooltipBox(androidx.compose.ui.window.PopupPositionProvider positionProvider, kotlin.jvm.functions.Function1<? super androidx.compose.material3.TooltipScope,kotlin.Unit> tooltip, androidx.compose.material3.TooltipState state, optional androidx.compose.ui.Modifier modifier, optional boolean focusable, optional boolean enableUserInput, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public static androidx.compose.material3.TooltipState TooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.TooltipState rememberTooltipState(optional boolean initialIsVisible, optional boolean isPersistent, optional androidx.compose.foundation.MutatorMutex mutatorMutex);
@@ -2035,6 +2033,11 @@
property public abstract androidx.compose.animation.core.MutableTransitionState<java.lang.Boolean> transition;
}
+ public final class Tooltip_androidKt {
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void PlainTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional long contentColor, optional long containerColor, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void RichTooltip(androidx.compose.material3.TooltipScope, optional androidx.compose.ui.Modifier modifier, optional kotlin.jvm.functions.Function0<kotlin.Unit>? title, optional kotlin.jvm.functions.Function0<kotlin.Unit>? action, optional long caretSize, optional androidx.compose.ui.graphics.Shape shape, optional androidx.compose.material3.RichTooltipColors colors, optional float tonalElevation, optional float shadowElevation, kotlin.jvm.functions.Function0<kotlin.Unit> text);
+ }
+
@SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Stable public final class TopAppBarColors {
ctor public TopAppBarColors(long containerColor, long scrolledContainerColor, long navigationIconContentColor, long titleContentColor, long actionIconContentColor);
method public androidx.compose.material3.TopAppBarColors copy(optional long containerColor, optional long scrolledContainerColor, optional long navigationIconContentColor, optional long titleContentColor, optional long actionIconContentColor);
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Tooltip.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Tooltip.android.kt
index b42e087..8777756 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Tooltip.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/Tooltip.android.kt
@@ -16,12 +16,320 @@
package androidx.compose.material3
+import android.content.res.Configuration
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.paddingFromBaseline
+import androidx.compose.foundation.layout.requiredHeightIn
+import androidx.compose.foundation.layout.sizeIn
+import androidx.compose.material3.tokens.PlainTooltipTokens
+import androidx.compose.material3.tokens.RichTooltipTokens
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.CacheDrawScope
+import androidx.compose.ui.draw.DrawResult
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.isSpecified
+/**
+ * Plain tooltip that provides a descriptive message.
+ *
+ * Usually used with [TooltipBox].
+ *
+ * @param modifier the [Modifier] to be applied to the tooltip.
+ * @param caretSize [DpSize] for the caret of the tooltip, if a default
+ * caret is desired with a specific dimension. Please see [TooltipDefaults.caretSize] to
+ * see the default dimensions. Pass in Dp.Unspecified for this parameter if no caret is desired.
+ * @param shape the [Shape] that should be applied to the tooltip container.
+ * @param contentColor [Color] that will be applied to the tooltip's content.
+ * @param containerColor [Color] that will be applied to the tooltip's container.
+ * @param tonalElevation the tonal elevation of the tooltip.
+ * @param shadowElevation the shadow elevation of the tooltip.
+ * @param content the composable that will be used to populate the tooltip's content.
+ */
@Composable
-internal actual fun windowContainerWidthInPx(): Int = with(LocalDensity.current) {
- LocalConfiguration.current.screenWidthDp.dp.roundToPx()
+@ExperimentalMaterial3Api
+actual fun TooltipScope.PlainTooltip(
+ modifier: Modifier,
+ caretSize: DpSize,
+ shape: Shape,
+ contentColor: Color,
+ containerColor: Color,
+ tonalElevation: Dp,
+ shadowElevation: Dp,
+ content: @Composable () -> Unit
+) {
+ val drawCaretModifier =
+ if (caretSize.isSpecified) {
+ val density = LocalDensity.current
+ val configuration = LocalConfiguration.current
+ Modifier.drawCaret { anchorLayoutCoordinates ->
+ drawCaretWithPath(
+ CaretType.Plain,
+ density,
+ configuration,
+ containerColor,
+ caretSize,
+ anchorLayoutCoordinates
+ )
+ }.then(modifier)
+ } else modifier
+ Surface(
+ modifier = drawCaretModifier,
+ shape = shape,
+ color = containerColor,
+ tonalElevation = tonalElevation,
+ shadowElevation = shadowElevation
+ ) {
+ Box(modifier = Modifier
+ .sizeIn(
+ minWidth = TooltipMinWidth,
+ maxWidth = PlainTooltipMaxWidth,
+ minHeight = TooltipMinHeight
+ )
+ .padding(PlainTooltipContentPadding)
+ ) {
+ val textStyle =
+ PlainTooltipTokens.SupportingTextFont.value
+
+ CompositionLocalProvider(
+ LocalContentColor provides contentColor,
+ LocalTextStyle provides textStyle,
+ content = content
+ )
+ }
+ }
+}
+
+/**
+ * Rich text tooltip that allows the user to pass in a title, text, and action.
+ * Tooltips are used to provide a descriptive message.
+ *
+ * Usually used with [TooltipBox]
+ *
+ * @param modifier the [Modifier] to be applied to the tooltip.
+ * @param title An optional title for the tooltip.
+ * @param action An optional action for the tooltip.
+ * @param caretSize [DpSize] for the caret of the tooltip, if a default
+ * caret is desired with a specific dimension. Please see [TooltipDefaults.caretSize] to
+ * see the default dimensions. Pass in Dp.Unspecified for this parameter if no caret is desired.
+ * @param shape the [Shape] that should be applied to the tooltip container.
+ * @param colors [RichTooltipColors] that will be applied to the tooltip's container and content.
+ * @param tonalElevation the tonal elevation of the tooltip.
+ * @param shadowElevation the shadow elevation of the tooltip.
+ * @param text the composable that will be used to populate the rich tooltip's text.
+ */
+@Composable
+@ExperimentalMaterial3Api
+actual fun TooltipScope.RichTooltip(
+ modifier: Modifier,
+ title: (@Composable () -> Unit)?,
+ action: (@Composable () -> Unit)?,
+ caretSize: DpSize,
+ shape: Shape,
+ colors: RichTooltipColors,
+ tonalElevation: Dp,
+ shadowElevation: Dp,
+ text: @Composable () -> Unit
+) {
+ val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
+ val elevatedColor =
+ MaterialTheme.colorScheme.applyTonalElevation(
+ colors.containerColor,
+ absoluteElevation
+ )
+ val drawCaretModifier =
+ if (caretSize.isSpecified) {
+ val density = LocalDensity.current
+ val configuration = LocalConfiguration.current
+ Modifier.drawCaret { anchorLayoutCoordinates ->
+ drawCaretWithPath(
+ CaretType.Rich,
+ density,
+ configuration,
+ elevatedColor,
+ caretSize,
+ anchorLayoutCoordinates
+ )
+ }.then(modifier)
+ } else modifier
+ Surface(
+ modifier = drawCaretModifier
+ .sizeIn(
+ minWidth = TooltipMinWidth,
+ maxWidth = RichTooltipMaxWidth,
+ minHeight = TooltipMinHeight
+ ),
+ shape = shape,
+ color = colors.containerColor,
+ tonalElevation = tonalElevation,
+ shadowElevation = shadowElevation
+ ) {
+ val actionLabelTextStyle = RichTooltipTokens.ActionLabelTextFont.value
+ val subheadTextStyle = RichTooltipTokens.SubheadFont.value
+ val supportingTextStyle = RichTooltipTokens.SupportingTextFont.value
+
+ Column(
+ modifier = Modifier.padding(horizontal = RichTooltipHorizontalPadding)
+ ) {
+ title?.let {
+ Box(
+ modifier = Modifier.paddingFromBaseline(top = HeightToSubheadFirstLine)
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.titleContentColor,
+ LocalTextStyle provides subheadTextStyle,
+ content = it
+ )
+ }
+ }
+ Box(
+ modifier = Modifier.textVerticalPadding(
+ title != null,
+ action != null
+ )
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.contentColor,
+ LocalTextStyle provides supportingTextStyle,
+ content = text
+ )
+ }
+ action?.let {
+ Box(
+ modifier = Modifier
+ .requiredHeightIn(min = ActionLabelMinHeight)
+ .padding(bottom = ActionLabelBottomPadding)
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.actionContentColor,
+ LocalTextStyle provides actionLabelTextStyle,
+ content = it
+ )
+ }
+ }
+ }
+ }
+}
+
+@ExperimentalMaterial3Api
+private fun CacheDrawScope.drawCaretWithPath(
+ caretType: CaretType,
+ density: Density,
+ configuration: Configuration,
+ containerColor: Color,
+ caretSize: DpSize,
+ anchorLayoutCoordinates: LayoutCoordinates?
+): DrawResult {
+ val path = Path()
+
+ if (anchorLayoutCoordinates != null) {
+ val caretHeightPx: Int
+ val caretWidthPx: Int
+ val screenWidthPx: Int
+ val tooltipAnchorSpacing: Int
+ with(density) {
+ caretHeightPx = caretSize.height.roundToPx()
+ caretWidthPx = caretSize.width.roundToPx()
+ screenWidthPx = configuration.screenWidthDp.dp.roundToPx()
+ tooltipAnchorSpacing = SpacingBetweenTooltipAndAnchor.roundToPx()
+ }
+ val anchorBounds = anchorLayoutCoordinates.boundsInWindow()
+ val anchorLeft = anchorBounds.left
+ val anchorRight = anchorBounds.right
+ val anchorTop = anchorBounds.top
+ val anchorMid = (anchorRight + anchorLeft) / 2
+ val anchorWidth = anchorRight - anchorLeft
+ val tooltipWidth = this.size.width
+ val tooltipHeight = this.size.height
+ val isCaretTop = anchorTop - tooltipHeight - tooltipAnchorSpacing < 0
+ val caretY = if (isCaretTop) { 0f } else { tooltipHeight }
+
+ val position: Offset
+ if (caretType == CaretType.Plain) {
+ position =
+ if (anchorMid + tooltipWidth / 2 > screenWidthPx) {
+ // Caret needs to be near the right
+ val anchorMidFromRightScreenEdge =
+ screenWidthPx - anchorMid
+ val caretX = tooltipWidth - anchorMidFromRightScreenEdge
+ Offset(caretX, caretY)
+ } else {
+ // Caret needs to be near the left
+ val tooltipLeft =
+ anchorLeft - (this.size.width / 2 - anchorWidth / 2)
+ val caretX = anchorMid - maxOf(tooltipLeft, 0f)
+ Offset(caretX, caretY)
+ }
+ } else {
+ // Default the caret to the left
+ var preferredPosition = Offset(anchorMid - anchorLeft, caretY)
+ if (anchorLeft + tooltipWidth > screenWidthPx) {
+ // Need to move the caret to the right
+ preferredPosition = Offset(anchorMid - (anchorRight - tooltipWidth), caretY)
+ if (anchorRight - tooltipWidth < 0) {
+ // Need to center the caret
+ // Caret might need to be offset depending on where
+ // the tooltip is placed relative to the anchor
+ if (anchorLeft - tooltipWidth / 2 + anchorWidth / 2 <= 0) {
+ preferredPosition = Offset(anchorMid, caretY)
+ } else if (anchorRight + tooltipWidth / 2 - anchorWidth / 2 >= screenWidthPx) {
+ val anchorMidFromRightScreenEdge =
+ screenWidthPx - anchorMid
+ val caretX = tooltipWidth - anchorMidFromRightScreenEdge
+ preferredPosition = Offset(caretX, caretY)
+ } else {
+ preferredPosition = Offset(tooltipWidth / 2, caretY)
+ }
+ }
+ }
+ position = preferredPosition
+ }
+
+ if (isCaretTop) {
+ path.apply {
+ moveTo(x = position.x, y = position.y)
+ lineTo(x = position.x + caretWidthPx / 2, y = position.y)
+ lineTo(x = position.x, y = position.y - caretHeightPx)
+ lineTo(x = position.x - caretWidthPx / 2, y = position.y)
+ close()
+ }
+ } else {
+ path.apply {
+ moveTo(x = position.x, y = position.y)
+ lineTo(x = position.x + caretWidthPx / 2, y = position.y)
+ lineTo(x = position.x, y = position.y + caretHeightPx.toFloat())
+ lineTo(x = position.x - caretWidthPx / 2, y = position.y)
+ close()
+ }
+ }
+ }
+
+ return onDrawWithContent {
+ if (anchorLayoutCoordinates != null) {
+ drawContent()
+ drawPath(
+ path = path,
+ color = containerColor
+ )
+ }
+ }
+}
+
+@ExperimentalMaterial3Api
+private enum class CaretType {
+ Plain, Rich
}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt
index 18f443c..a673371 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tooltip.kt
@@ -26,42 +26,35 @@
import androidx.compose.foundation.MutatePriority
import androidx.compose.foundation.MutatorMutex
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.paddingFromBaseline
-import androidx.compose.foundation.layout.requiredHeightIn
-import androidx.compose.foundation.layout.sizeIn
import androidx.compose.material3.internal.BasicTooltipBox
import androidx.compose.material3.internal.BasicTooltipDefaults
import androidx.compose.material3.tokens.ElevationTokens
import androidx.compose.material3.tokens.PlainTooltipTokens
import androidx.compose.material3.tokens.RichTooltipTokens
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.CacheDrawScope
import androidx.compose.ui.draw.DrawResult
import androidx.compose.ui.draw.drawWithCache
-import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.layout.LayoutCoordinates
-import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.debugInspectorInfo
-import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.IntOffset
@@ -69,7 +62,6 @@
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.isSpecified
import androidx.compose.ui.window.PopupPositionProvider
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -208,7 +200,7 @@
*/
@Composable
@ExperimentalMaterial3Api
-fun TooltipScope.PlainTooltip(
+expect fun TooltipScope.PlainTooltip(
modifier: Modifier = Modifier,
caretSize: DpSize = DpSize.Unspecified,
shape: Shape = TooltipDefaults.plainTooltipContainerShape,
@@ -217,48 +209,7 @@
tonalElevation: Dp = 0.dp,
shadowElevation: Dp = 0.dp,
content: @Composable () -> Unit
-) {
- val drawCaretModifier =
- if (caretSize.isSpecified) {
- val density = LocalDensity.current
- val windowContainerWidthInPx = windowContainerWidthInPx()
- Modifier.drawCaret { anchorLayoutCoordinates ->
- drawCaretWithPath(
- CaretType.Plain,
- density,
- windowContainerWidthInPx,
- containerColor,
- caretSize,
- anchorLayoutCoordinates
- )
- }.then(modifier)
- } else modifier
- Surface(
- modifier = drawCaretModifier,
- shape = shape,
- color = containerColor,
- tonalElevation = tonalElevation,
- shadowElevation = shadowElevation
- ) {
- Box(modifier = Modifier
- .sizeIn(
- minWidth = TooltipMinWidth,
- maxWidth = PlainTooltipMaxWidth,
- minHeight = TooltipMinHeight
- )
- .padding(PlainTooltipContentPadding)
- ) {
- val textStyle =
- PlainTooltipTokens.SupportingTextFont.value
-
- CompositionLocalProvider(
- LocalContentColor provides contentColor,
- LocalTextStyle provides textStyle,
- content = content
- )
- }
- }
-}
+)
/**
* Rich text tooltip that allows the user to pass in a title, text, and action.
@@ -280,7 +231,7 @@
*/
@Composable
@ExperimentalMaterial3Api
-fun TooltipScope.RichTooltip(
+expect fun TooltipScope.RichTooltip(
modifier: Modifier = Modifier,
title: (@Composable () -> Unit)? = null,
action: (@Composable () -> Unit)? = null,
@@ -290,86 +241,7 @@
tonalElevation: Dp = ElevationTokens.Level0,
shadowElevation: Dp = RichTooltipTokens.ContainerElevation,
text: @Composable () -> Unit
-) {
- val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
- val elevatedColor =
- MaterialTheme.colorScheme.applyTonalElevation(
- colors.containerColor,
- absoluteElevation
- )
- val drawCaretModifier =
- if (caretSize.isSpecified) {
- val density = LocalDensity.current
- val windowContainerWidthInPx = windowContainerWidthInPx()
- Modifier.drawCaret { anchorLayoutCoordinates ->
- drawCaretWithPath(
- CaretType.Rich,
- density,
- windowContainerWidthInPx,
- elevatedColor,
- caretSize,
- anchorLayoutCoordinates
- )
- }.then(modifier)
- } else modifier
- Surface(
- modifier = drawCaretModifier
- .sizeIn(
- minWidth = TooltipMinWidth,
- maxWidth = RichTooltipMaxWidth,
- minHeight = TooltipMinHeight
- ),
- shape = shape,
- color = colors.containerColor,
- tonalElevation = tonalElevation,
- shadowElevation = shadowElevation
- ) {
- val actionLabelTextStyle = RichTooltipTokens.ActionLabelTextFont.value
- val subheadTextStyle = RichTooltipTokens.SubheadFont.value
- val supportingTextStyle = RichTooltipTokens.SupportingTextFont.value
-
- Column(
- modifier = Modifier.padding(horizontal = RichTooltipHorizontalPadding)
- ) {
- title?.let {
- Box(
- modifier = Modifier.paddingFromBaseline(top = HeightToSubheadFirstLine)
- ) {
- CompositionLocalProvider(
- LocalContentColor provides colors.titleContentColor,
- LocalTextStyle provides subheadTextStyle,
- content = it
- )
- }
- }
- Box(
- modifier = Modifier.textVerticalPadding(
- title != null,
- action != null
- )
- ) {
- CompositionLocalProvider(
- LocalContentColor provides colors.contentColor,
- LocalTextStyle provides supportingTextStyle,
- content = text
- )
- }
- action?.let {
- Box(
- modifier = Modifier
- .requiredHeightIn(min = ActionLabelMinHeight)
- .padding(bottom = ActionLabelBottomPadding)
- ) {
- CompositionLocalProvider(
- LocalContentColor provides colors.actionContentColor,
- LocalTextStyle provides actionLabelTextStyle,
- content = it
- )
- }
- }
- }
- }
-}
+)
/**
* Tooltip defaults that contain default values for both [PlainTooltip] and [RichTooltip]
@@ -638,7 +510,7 @@
override val isVisible: Boolean
get() = transition.currentState || transition.targetState
- /**
+ /**
* continuation used to clean up
*/
private var job: (CancellableContinuation<Unit>)? = null
@@ -812,118 +684,6 @@
)
}
-@ExperimentalMaterial3Api
-private fun CacheDrawScope.drawCaretWithPath(
- caretType: CaretType,
- density: Density,
- windowContainerWidthInPx: Int,
- containerColor: Color,
- caretSize: DpSize,
- anchorLayoutCoordinates: LayoutCoordinates?
-): DrawResult {
- val path = Path()
-
- if (anchorLayoutCoordinates != null) {
- val caretHeightPx: Int
- val caretWidthPx: Int
- val tooltipAnchorSpacing: Int
- with(density) {
- caretHeightPx = caretSize.height.roundToPx()
- caretWidthPx = caretSize.width.roundToPx()
- tooltipAnchorSpacing = SpacingBetweenTooltipAndAnchor.roundToPx()
- }
- val anchorBounds = anchorLayoutCoordinates.boundsInWindow()
- val anchorLeft = anchorBounds.left
- val anchorRight = anchorBounds.right
- val anchorTop = anchorBounds.top
- val anchorMid = (anchorRight + anchorLeft) / 2
- val anchorWidth = anchorRight - anchorLeft
- val tooltipWidth = this.size.width
- val tooltipHeight = this.size.height
- val isCaretTop = anchorTop - tooltipHeight - tooltipAnchorSpacing < 0
- val caretY = if (isCaretTop) { 0f } else { tooltipHeight }
-
- val position: Offset
- if (caretType == CaretType.Plain) {
- position =
- if (anchorMid + tooltipWidth / 2 > windowContainerWidthInPx) {
- // Caret needs to be near the right
- val anchorMidFromRightScreenEdge =
- windowContainerWidthInPx - anchorMid
- val caretX = tooltipWidth - anchorMidFromRightScreenEdge
- Offset(caretX, caretY)
- } else {
- // Caret needs to be near the left
- val tooltipLeft =
- anchorLeft - (this.size.width / 2 - anchorWidth / 2)
- val caretX = anchorMid - maxOf(tooltipLeft, 0f)
- Offset(caretX, caretY)
- }
- } else {
- // Default the caret to the left
- var preferredPosition = Offset(anchorMid - anchorLeft, caretY)
- if (anchorLeft + tooltipWidth > windowContainerWidthInPx) {
- // Need to move the caret to the right
- preferredPosition = Offset(anchorMid - (anchorRight - tooltipWidth), caretY)
- if (anchorRight - tooltipWidth < 0) {
- // Need to center the caret
- // Caret might need to be offset depending on where
- // the tooltip is placed relative to the anchor
- if (anchorLeft - tooltipWidth / 2 + anchorWidth / 2 <= 0) {
- preferredPosition = Offset(anchorMid, caretY)
- } else if (
- anchorRight + tooltipWidth / 2 - anchorWidth / 2 >= windowContainerWidthInPx
- ) {
- val anchorMidFromRightScreenEdge =
- windowContainerWidthInPx - anchorMid
- val caretX = tooltipWidth - anchorMidFromRightScreenEdge
- preferredPosition = Offset(caretX, caretY)
- } else {
- preferredPosition = Offset(tooltipWidth / 2, caretY)
- }
- }
- }
- position = preferredPosition
- }
-
- if (isCaretTop) {
- path.apply {
- moveTo(x = position.x, y = position.y)
- lineTo(x = position.x + caretWidthPx / 2, y = position.y)
- lineTo(x = position.x, y = position.y - caretHeightPx)
- lineTo(x = position.x - caretWidthPx / 2, y = position.y)
- close()
- }
- } else {
- path.apply {
- moveTo(x = position.x, y = position.y)
- lineTo(x = position.x + caretWidthPx / 2, y = position.y)
- lineTo(x = position.x, y = position.y + caretHeightPx.toFloat())
- lineTo(x = position.x - caretWidthPx / 2, y = position.y)
- close()
- }
- }
- }
-
- return onDrawWithContent {
- if (anchorLayoutCoordinates != null) {
- drawContent()
- drawPath(
- path = path,
- color = containerColor
- )
- }
- }
-}
-
-@ExperimentalMaterial3Api
-private enum class CaretType {
- Plain, Rich
-}
-
-@Composable
-internal expect fun windowContainerWidthInPx(): Int
-
internal val SpacingBetweenTooltipAndAnchor = 4.dp
internal val TooltipMinHeight = 24.dp
internal val TooltipMinWidth = 40.dp
diff --git a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Tooltip.desktop.kt b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Tooltip.desktop.kt
index c3cbf05..71f431b 100644
--- a/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Tooltip.desktop.kt
+++ b/compose/material3/material3/src/desktopMain/kotlin/androidx/compose/material3/Tooltip.desktop.kt
@@ -16,12 +16,158 @@
package androidx.compose.material3
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.paddingFromBaseline
+import androidx.compose.foundation.layout.requiredHeightIn
+import androidx.compose.foundation.layout.sizeIn
+import androidx.compose.material3.tokens.PlainTooltipTokens
+import androidx.compose.material3.tokens.RichTooltipTokens
import androidx.compose.runtime.Composable
-import androidx.compose.ui.LocalComposeScene
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
+/**
+ * Plain tooltip that provides a descriptive message.
+ *
+ * Usually used with [TooltipBox].
+ *
+ * @param modifier the [Modifier] to be applied to the tooltip.
+ * @param caretSize [DpSize] for the caret of the tooltip, if a default
+ * caret is desired with a specific dimension. Please see [TooltipDefaults.caretSize] to
+ * see the default dimensions. Pass in Dp.Unspecified for this parameter if no caret is desired.
+ * @param shape the [Shape] that should be applied to the tooltip container.
+ * @param contentColor [Color] that will be applied to the tooltip's content.
+ * @param containerColor [Color] that will be applied to the tooltip's container.
+ * @param tonalElevation the tonal elevation of the tooltip.
+ * @param shadowElevation the shadow elevation of the tooltip.
+ * @param content the composable that will be used to populate the tooltip's content.
+ */
@Composable
-internal actual fun windowContainerWidthInPx(): Int {
- // TODO: Upstream a proper way to get this from JetBrains fork
- // LocalWindowInfo.current.containerSize.width
- return LocalComposeScene.current.constraints.maxWidth
+@ExperimentalMaterial3Api
+actual fun TooltipScope.PlainTooltip(
+ modifier: Modifier,
+ caretSize: DpSize,
+ shape: Shape,
+ contentColor: Color,
+ containerColor: Color,
+ tonalElevation: Dp,
+ shadowElevation: Dp,
+ content: @Composable () -> Unit
+) {
+ Surface(
+ modifier = modifier,
+ shape = shape,
+ color = containerColor,
+ tonalElevation = tonalElevation,
+ shadowElevation = shadowElevation
+ ) {
+ Box(modifier = Modifier
+ .sizeIn(
+ minWidth = TooltipMinWidth,
+ maxWidth = PlainTooltipMaxWidth,
+ minHeight = TooltipMinHeight
+ )
+ .padding(PlainTooltipContentPadding)
+ ) {
+ val textStyle = PlainTooltipTokens.SupportingTextFont.value
+ CompositionLocalProvider(
+ LocalContentColor provides contentColor,
+ LocalTextStyle provides textStyle,
+ content = content
+ )
+ }
+ }
+}
+
+/**
+ * Rich text tooltip that allows the user to pass in a title, text, and action.
+ * Tooltips are used to provide a descriptive message.
+ *
+ * Usually used with [TooltipBox]
+ *
+ * @param modifier the [Modifier] to be applied to the tooltip.
+ * @param title An optional title for the tooltip.
+ * @param action An optional action for the tooltip.
+ * @param caretSize [DpSize] for the caret of the tooltip, if a default
+ * caret is desired with a specific dimension. Please see [TooltipDefaults.caretSize] to
+ * see the default dimensions. Pass in Dp.Unspecified for this parameter if no caret is desired.
+ * @param shape the [Shape] that should be applied to the tooltip container.
+ * @param colors [RichTooltipColors] that will be applied to the tooltip's container and content.
+ * @param tonalElevation the tonal elevation of the tooltip.
+ * @param shadowElevation the shadow elevation of the tooltip.
+ * @param text the composable that will be used to populate the rich tooltip's text.
+ */
+@Composable
+@ExperimentalMaterial3Api
+actual fun TooltipScope.RichTooltip(
+ modifier: Modifier,
+ title: (@Composable () -> Unit)?,
+ action: (@Composable () -> Unit)?,
+ caretSize: DpSize,
+ shape: Shape,
+ colors: RichTooltipColors,
+ tonalElevation: Dp,
+ shadowElevation: Dp,
+ text: @Composable () -> Unit
+) {
+ Surface(
+ modifier = modifier
+ .sizeIn(
+ minWidth = TooltipMinWidth,
+ maxWidth = RichTooltipMaxWidth,
+ minHeight = TooltipMinHeight
+ ),
+ shape = shape,
+ color = colors.containerColor,
+ tonalElevation = tonalElevation,
+ shadowElevation = shadowElevation
+ ) {
+ val actionLabelTextStyle = RichTooltipTokens.ActionLabelTextFont.value
+ val subheadTextStyle = RichTooltipTokens.SubheadFont.value
+ val supportingTextStyle = RichTooltipTokens.SupportingTextFont.value
+
+ Column(
+ modifier = Modifier.padding(horizontal = RichTooltipHorizontalPadding)
+ ) {
+ title?.let {
+ Box(
+ modifier = Modifier.paddingFromBaseline(top = HeightToSubheadFirstLine)
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.titleContentColor,
+ LocalTextStyle provides subheadTextStyle,
+ content = it
+ )
+ }
+ }
+ Box(
+ modifier = Modifier.textVerticalPadding(title != null, action != null)
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.contentColor,
+ LocalTextStyle provides supportingTextStyle,
+ content = text
+ )
+ }
+ action?.let {
+ Box(
+ modifier = Modifier
+ .requiredHeightIn(min = ActionLabelMinHeight)
+ .padding(bottom = ActionLabelBottomPadding)
+ ) {
+ CompositionLocalProvider(
+ LocalContentColor provides colors.actionContentColor,
+ LocalTextStyle provides actionLabelTextStyle,
+ content = it
+ )
+ }
+ }
+ }
+ }
}
diff --git a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
index d510fac..2f16c79 100644
--- a/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
+++ b/compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/ComposeScene.skiko.kt
@@ -56,9 +56,7 @@
import kotlinx.coroutines.launch
import org.jetbrains.skia.Canvas
-// TODO: This val should not be public!
-// Upstream current state of [ComposeScene] from JetBrains fork
-val LocalComposeScene = staticCompositionLocalOf<ComposeScene> {
+internal val LocalComposeScene = staticCompositionLocalOf<ComposeScene> {
error("CompositionLocal LocalComposeScene not provided")
}