diff --git a/compose/api/compose.klib.api b/compose/api/compose.klib.api index 3ea50f2..6d4064d 100644 --- a/compose/api/compose.klib.api +++ b/compose/api/compose.klib.api @@ -705,6 +705,8 @@ final object app.tinyui.components.generated/BuiltinSchemas { // app.tinyui.comp final fun (): app.tinyui.schema/ComponentSchema // app.tinyui.components.generated/BuiltinSchemas.Loading.|(){}[0] final val Option // app.tinyui.components.generated/BuiltinSchemas.Option|{}Option[0] final fun (): app.tinyui.schema/ComponentSchema // app.tinyui.components.generated/BuiltinSchemas.Option.|(){}[0] + final val Popover // app.tinyui.components.generated/BuiltinSchemas.Popover|{}Popover[0] + final fun (): app.tinyui.schema/ComponentSchema // app.tinyui.components.generated/BuiltinSchemas.Popover.|(){}[0] final val RadioButton // app.tinyui.components.generated/BuiltinSchemas.RadioButton|{}RadioButton[0] final fun (): app.tinyui.schema/ComponentSchema // app.tinyui.components.generated/BuiltinSchemas.RadioButton.|(){}[0] final val Row // app.tinyui.components.generated/BuiltinSchemas.Row|{}Row[0] diff --git a/compose/src/commonMain/kotlin/app/tinyui/components/Builtins.kt b/compose/src/commonMain/kotlin/app/tinyui/components/Builtins.kt index 3bec050..116b19f 100644 --- a/compose/src/commonMain/kotlin/app/tinyui/components/Builtins.kt +++ b/compose/src/commonMain/kotlin/app/tinyui/components/Builtins.kt @@ -1,5 +1,9 @@ package app.tinyui.components +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.MutableTransitionState +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.horizontalScroll @@ -13,6 +17,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.LazyListState @@ -44,6 +49,7 @@ import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.RadioButton import androidx.compose.material3.SheetValue +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberBottomSheetState @@ -65,6 +71,9 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.Layout +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.semantics.contentType @@ -86,6 +95,13 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntRect +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.LayoutDirection +import androidx.compose.ui.window.Popup +import androidx.compose.ui.window.PopupPositionProvider +import androidx.compose.ui.window.PopupProperties import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put @@ -177,6 +193,7 @@ fun ComponentRegistry.registerBuiltins(): ComponentRegistry = apply { } register(BuiltinSchemas.Loading) { scope -> LoadingComponent(scope) } register(BuiltinSchemas.BottomSheet) { scope -> BottomSheetComponent(scope) } + register(BuiltinSchemas.Popover) { scope -> PopoverComponent(scope) } register(BuiltinSchemas.Divider) { scope -> HorizontalDivider( modifier = scope.modifier(), @@ -491,3 +508,71 @@ private fun BottomSheetComponent(scope: NodeScope) { ) { scope.Children() } } } + +/** + * A card next to the parent node, which is the anchor: Compose's `Popup` anchors to the layout it is called in, and + * built-ins render their children without wrappers. Visibility follows `open` (faded); a tap outside is only reported, + * since the field the user just tapped is "outside" too. Never focusable: a hint under a focused field must not take + * the keyboard away. + */ +@Composable +private fun PopoverComponent(scope: NodeScope) { + val visible = remember { MutableTransitionState(false) } + visible.targetState = scope.get("open") == true + // stays composed while fading out + if (!visible.currentState && !visible.targetState) return + val matchWidth = scope.get("matchAnchorWidth") == true + var anchorWidth by remember { mutableStateOf(null) } + if (matchWidth) { + // the same zero-size probe Popup itself uses to find its parent + Layout(content = {}, modifier = Modifier.onGloballyPositioned { anchorWidth = it.parentLayoutCoordinates?.size?.width }) { _, _ -> layout(0, 0) {} } + // not drawn until the width is known, so it never shows at the wrong width first + if (anchorWidth == null) return + } + val gap = with(LocalDensity.current) { POPOVER_GAP.roundToPx() } + val above = scope.get("placement") == "above" + val position = remember(above, gap) { + object : PopupPositionProvider { + override fun calculatePosition(anchorBounds: IntRect, windowSize: IntSize, layoutDirection: LayoutDirection, popupContentSize: IntSize) = + popoverOffset(anchorBounds, windowSize, popupContentSize, above, gap, layoutDirection == LayoutDirection.Rtl) + } + } + val width = anchorWidth?.takeIf { matchWidth }?.let { with(LocalDensity.current) { it.toDp() } } + Popup( + popupPositionProvider = position, + onDismissRequest = { if (scope.has("onDismiss")) scope.dispatch("onDismiss") }, + properties = PopupProperties(focusable = false), + ) { + AnimatedVisibility(visibleState = visible, enter = fadeIn(), exit = fadeOut()) { + Surface( + modifier = if (width != null) Modifier.width(width) else Modifier, + shape = MaterialTheme.shapes.medium, + // explicit: contentColorFor would guess from the container and can land on a muted colour + color = MaterialTheme.colorScheme.surface, + contentColor = MaterialTheme.colorScheme.onSurface, + shadowElevation = 3.dp, + ) { scope.Children() } + } + } +} + +private val POPOVER_GAP = 8.dp + +/** + * Where a popover of [content] size goes: on the [above] / below side of [anchor] with [gap] px between, start edges + * aligned. The preferred side wins when it fits, else the other side when that fits, else the roomier side; the result + * is kept inside [window] on both axes. + */ +internal fun popoverOffset(anchor: IntRect, window: IntSize, content: IntSize, above: Boolean, gap: Int, rtl: Boolean): IntOffset { + val topY = anchor.top - gap - content.height + val bottomY = anchor.bottom + gap + val fitsTop = topY >= 0 + val fitsBottom = bottomY + content.height <= window.height + val roomierTop = anchor.top > window.height - anchor.bottom + val onTop = if (above) fitsTop || !fitsBottom && roomierTop else !fitsBottom && (fitsTop || roomierTop) + val x = if (rtl) anchor.right - content.width else anchor.left + return IntOffset( + x.coerceIn(0, (window.width - content.width).coerceAtLeast(0)), + (if (onTop) topY else bottomY).coerceIn(0, (window.height - content.height).coerceAtLeast(0)), + ) +} diff --git a/compose/src/commonMain/kotlin/app/tinyui/components/generated/BuiltinSchemas.kt b/compose/src/commonMain/kotlin/app/tinyui/components/generated/BuiltinSchemas.kt index 5c6fc82..2f0bd22 100644 --- a/compose/src/commonMain/kotlin/app/tinyui/components/generated/BuiltinSchemas.kt +++ b/compose/src/commonMain/kotlin/app/tinyui/components/generated/BuiltinSchemas.kt @@ -292,7 +292,23 @@ object BuiltinSchemas { layout = false, ) - val all: List = listOf(Column, Row, Box, Text, Button, RadioButton, TextField, LazyColumn, Spacer, Icon, Loading, BottomSheet, Divider, Checkbox, CodeField, Select, Option) + val Popover = ComponentSchema( + type = "Popover", + props = mapOf( + "open" to PropSpec.Bool(default = null, required = true, initial = false), + "placement" to PropSpec.Enum(values = setOf("above", "below"), default = "below", required = false, initial = false), + "matchAnchorWidth" to PropSpec.Bool(default = false, required = false, initial = false), + ), + events = mapOf( + "onDismiss" to emptyMap(), + ), + commands = mapOf( + ), + children = true, + layout = false, + ) + + val all: List = listOf(Column, Row, Box, Text, Button, RadioButton, TextField, LazyColumn, Spacer, Icon, Loading, BottomSheet, Divider, Checkbox, CodeField, Select, Option, Popover) /** Theme token names the schema DSL knows; Theme.kt must resolve each (checked by test). */ val colorTokens: Set = setOf("primary", "onPrimary", "primaryContainer", "onPrimaryContainer", "inversePrimary", "secondary", "onSecondary", "secondaryContainer", "onSecondaryContainer", "tertiary", "onTertiary", "tertiaryContainer", "onTertiaryContainer", "background", "onBackground", "surface", "onSurface", "surfaceVariant", "onSurfaceVariant", "surfaceTint", "inverseSurface", "inverseOnSurface", "error", "onError", "errorContainer", "onErrorContainer", "outline", "outlineVariant", "scrim", "surfaceBright", "surfaceDim", "surfaceContainer", "surfaceContainerHigh", "surfaceContainerHighest", "surfaceContainerLow", "surfaceContainerLowest", "primaryFixed", "primaryFixedDim", "onPrimaryFixed", "onPrimaryFixedVariant", "secondaryFixed", "secondaryFixedDim", "onSecondaryFixed", "onSecondaryFixedVariant", "tertiaryFixed", "tertiaryFixedDim", "onTertiaryFixed", "onTertiaryFixedVariant") diff --git a/compose/src/commonMain/kotlin/app/tinyui/generated/RuntimeBytecode.kt b/compose/src/commonMain/kotlin/app/tinyui/generated/RuntimeBytecode.kt index 664d713..7d87a6f 100644 --- a/compose/src/commonMain/kotlin/app/tinyui/generated/RuntimeBytecode.kt +++ b/compose/src/commonMain/kotlin/app/tinyui/generated/RuntimeBytecode.kt @@ -4,7 +4,7 @@ package app.tinyui.generated /** Base64 of the runtime modules' bytecode, split to fit JVM string constants. */ internal object RuntimeBytecode { val core: Array = arrayOf( - "UUpLQjQAAAABAAAAMDRiZTI0NjAwMTU5OWY1OTk1ZmEyZjJkOGM5MWEwZjE5OGQzZjM0YwWhAhZ0aW55dWktY29yZRZCb3R0b21TaGVldAZCb3gMQnV0dG9uEENoZWNrYm94EkNvZGVGaWVsZAxDb2x1bW4ORGl2aWRlcgZGb3IQRnJhZ21lbnQSSG9zdEVycm9yCEljb24UTGF6eUNvbHVtbg5Mb2FkaW5nDE9wdGlvbhZSYWRpb0J1dHRvbgZSb3cMU2VsZWN0CFNob3cMU3BhY2VyCFRleHQSVGV4dEZpZWxkDlZFUlNJT04MZWZmZWN0AmgQaW50ZXJuYWwQbWFuaWZlc3QIbWVtbxRvYnNlcnZhYmxlEm9uQ2xlYW51cBZwYWdlVmlzaWJsZQZyZWYQcmVzb3VyY2UMc2lnbmFsCnRodW5rDnVudHJhY2sMdW53cmFwEl9fZGVmUHJvcBBfX2V4cG9ydBpjdXJyZW50RWZmZWN0GGN1cnJlbnRPd25lcg5wZW5kaW5nBnJhbiRNQVhfUlVOU19QRVJfRkxVU0gWY3JlYXRlT3duZXIYcnVuV2l0aE93bmVyGGRpc3Bvc2VPd25lchhpbnNpZGVSZW5kZXIQdHJhY2tpbmcUcnVuUGVuZGluZyRjcmVhdGVFZmZlY3RSZWNvcmQScnVuRWZmZWN0GmRpc3Bvc2VFZmZlY3QWdW5zdWJzY3JpYmUWcnVuQ2xlYW51cHMKdHJhY2sMbm90aWZ5DkNPTlRST0wKVGh1bmsOcGF0Y2hlcxBoYW5kbGVycwxuZXh0SWQQcmVzZXRJZHMIU2xvdBpjYWxsQ29tcG9uZW50GmNyZWF0ZUVsZW1lbnQQYmluZFByb3AMc2NhbGFyDmZsYXR0ZW4acmVuZGVySW5Pd25lchBwZW5kaW5nMhBuZXh0Q2JJZApxdWVyeQhjYWxsCHNlbmQMcmVwb3J0HHJlc29sdmVQZW5kaW5nGnJlamVjdFBlbmRpbmcaY2FuY2VsUGVuZGluZxhhbGxvY2F0ZUNiSWQecmVnaXN0ZXJQZW5kaW5nFHNldFRpbWVvdXQYY2xlYXJUaW1lb3V0HGluc3RhbGxHbG9iYWxzCHJvb3QOY3VycmVudA52aXNpYmxlFHNldFZpc2libGUMdG9waWNzDG9uRW1pdAxsaXN0ZW4OZ3VhcmRlZA5lbnRyaWVzDmluc3RhbGwGUkFXCEtFWVMOcHJveGllcxZzdWJzY3JpYmVycxR1bndyYXBEZWVwGnVud3JhcFNoYWxsb3cWaXNXcmFwcGFibGUId3JhcAhzdWJzDm9ic2VydmUOY2hhbmdlZA5pc0luZGV4EmhhbmRsZXJzMiBpbnRlcm5hbF9leHBvcnRzGF9faG9zdF9hcHBseRhfX2hvc3RfcXVlcnkWX19ob3N0X2NhbGwWX19ob3N0X3NlbmQaX19ob3N0X3JlcG9ydA5SZWZsZWN0DDAuMTMuMBx0aW55dWkuY29udHJvbAptb3VudAxpbnNlcnQIbW92ZQxyZW1vdmUMb2Zmc2V0DGFzc2lnbhRjb21wb25lbnRzGGNhcGFiaWxpdGllcw51bm1vdW50EGRpc3BhdGNoCGVtaXQKZmx1c2gUdGlueXVpLnJhdxZ0aW55dWkua2V5cwZhbGwOZWZmZWN0cxBjbGVhbnVwcxBkaXNwb3NlZApvd25lcgRmbhJwcmV2T3duZXIUcHJldkVmZmVjdAJlAmMMc3BsaWNlDnJldmVyc2UIaW5pdApzdWJzMgJ2DmVmZmVjdDICbQpkaXJ0eQhwdXNobG9uQ2xlYW51cCgpIGNhbGxlZCBvdXRzaWRlIGEgc3luY2hyb25vdXMgcmVuZGVyIHBlcmlvZAhwcmV2AmkMcXVldWVkCHJ1bnN8dXBkYXRlIGxvb3A6IGFuIGVmZmVjdCByZS1yYW4gbW9yZSB0aGFuIDEwMCB0aW1lcyBpbiBvbmUgZmx1c2hmZWZmZWN0KCkgY2FsbGVkIG91dHNpZGUgYSBzeW5jaHJvbm91cyByZW5kZXIgcGVyaW9kCGRlcHMMcGFyZW50EGVudHJpZXMyEHBvc2l0aW9uCm5vZGVzCG5vZGUEYXQEdG8OaW5kZXhPZixtb3ZlOiBub2RlIG5vdCBpbiBzbG90MHJlbW92ZTogbm9kZSBub3QgaW4gc2xvdAJyAm4EaWQGY21kCGFyZ3NecmVmLmNtZCgpIGJlZm9yZSB0aGUgcmVmIHdhcyBhdHRhY2hlZCB0byBhIG5vZGUCeBJGcmFnbWVudDIKcHJvcHMQY2hpbGRyZW4IdHlwZVxoKCkgY2FsbGVkIG91dHNpZGUgYSBzeW5jaHJvbm91cyByZW5kZXIgcGVyaW9kAnAGa2V5DHJlc3VsdAh3aGF0fGEgUHJvbWlzZSAoYXN5bmMgY29tcG9uZW50cyBhcmUgbm90IHN1cHBvcnRlZDsgdXNlIHJlc291cmNlKCkpDmlzQXJyYXlUc2V2ZXJhbCBub2RlcyAod3JhcCB0aGVtIGluIG9uZSBjb250YWluZXIpTmEgRm9yIC8gU2hvdyAod3JhcCBpdCBpbiBvbmUgY29udGFpbmVyKRRjb21wb25lbnQgFjxhbm9ueW1vdXM+RiBtdXN0IHJldHVybiBleGFjdGx5IG9uZSBub2RlLCBnb3QgAmsKY2hpbGQIdGVzdAI8AiAoPiBtdXN0IGJlIGEgZnVuY3Rpb24COghsYXN0CmZpcnN0AnRWPiBpcyBhIGZ1bmN0aW9uOyBkaWQgeW91IGZvcmdldCB0byBjYWxsIGl0P6oBPiBtdXN0IGJlIGEgc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4gb3IgbnVsbDsgcHJvcHMgZG8gbm90IGNyb3NzIHRoZSBicmlkZ2UgYXMgb2JqZWN0cwZvdXQMcmVuZGVyOiBtdXN0IHJldHVybiBleGFjdGx5IG9uZSBub2RlCGNvZGUOZGV0YWlscw5oZWFkZXJzCGJvZHkScGF0Y2hKc29uCnBhcnNlEnN0cmluZ2lmeQhjYklkCHNpdGUIa2luZAxkZXRhaWwUcmVzdWx0SnNvbhRFX0JBRF9KU09OMmhvc3QgcmVzdWx0IGlzIG5vdCBKU09OOiASZXJyb3JKc29uCmVycm9yIGhvc3QgY2FsbCBmYWlsZWQEbXMcdGltZXIuc2NoZWR1bGUYdGltZXIuY2FuY2VsAmcKdG9waWNmb25FbWl0KCkgY2FsbGVkIG91dHNpZGUgYSBzeW5jaHJvbm91cyByZW5kZXIgcGVyaW9kCmVudHJ5BmVycgRFMQhwYWdlEnByb3BzSnNvbhBob3N0SnNvbihtb3VudCgpIGNhbGxlZCB0d2ljZU5wYWdlIG11c3QgcmV0dXJuIGV4YWN0bHkgb25lIG5vZGUsIGdvdCASYSBQcm9taXNlCmNsZWFyDG5vZGVJZApldmVudBZwYXlsb2FkSnNvbg5oYW5kbGVyDnBheWxvYWQIanNvbhBfX3Rpbnl1aVpvYnNlcnZhYmxlKCkgdGFrZXMgYSBwbGFpbiBv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AAAAAAIAAQAGAPAFBhAAChFlAAAp5gMFkwYMAw8ADEIGAQAAAAAEAAUCHQDwBQYQAJoIARgAnggDGACgCAUYAJYIAAEAZAIACu0OZAMABu0OWwQA7D6EAAAAvgC+ASQCACnmAxOWBg4DExYUDRMWEA0PEQ4HBC8KAAxCBgEAAQABAgEDARMBhgYBAEDwBQASAJoIARoAnggCGgBkAADoAilkAQC+AO0OZAIACe0p5gMPmQYTAxEcAwgDGw4NDRYUAAxCBgEAAAAAAQABAAIAhgYAAQDbKOYDBZwGDgIMAAxCBgEAAQABAgADABIB+gUBAADwBQASAKAIAxoAnggCGgBkAADoAilkAQDP7Q5kAgAJ7SnmAxGeBgcDBhwDCAMREgcBDQ8WFAAMAgYBAAAAAAEAAQACAPgEMEIB2yjmAwWsBggCDAAMAgYBAAAAAAEAAQACAJoFQ0IB2yjmAwWtBgoCDAAMAgYBAAAAAAEAAQACAJgFQkIB2yjmAwWuBgoCDAAMAgYBAAAAAAEAAQACAPYEL0IB2yjmAwWvBgkCDAAMAgYBAAAAAAEAAQACAPoEMUIB2yjmAwWwBggCDAA=", + "UUpLQjQAAAABAAAAMDRiZTI0NjAwMTU5OWY1OTk1ZmEyZjJkOGM5MWEwZjE5OGQzZjM0YwWiAhZ0aW55dWktY29yZRZCb3R0b21TaGVldAZCb3gMQnV0dG9uEENoZWNrYm94EkNvZGVGaWVsZAxDb2x1bW4ORGl2aWRlcgZGb3IQRnJhZ21lbnQSSG9zdEVycm9yCEljb24UTGF6eUNvbHVtbg5Mb2FkaW5nDE9wdGlvbg5Qb3BvdmVyFlJhZGlvQnV0dG9uBlJvdwxTZWxlY3QIU2hvdwxTcGFjZXIIVGV4dBJUZXh0RmllbGQOVkVSU0lPTgxlZmZlY3QCaBBpbnRlcm5hbBBtYW5pZmVzdAhtZW1vFG9ic2VydmFibGUSb25DbGVhbnVwFnBhZ2VWaXNpYmxlBnJlZhByZXNvdXJjZQxzaWduYWwKdGh1bmsOdW50cmFjawx1bndyYXASX19kZWZQcm9wEF9fZXhwb3J0GmN1cnJlbnRFZmZlY3QYY3VycmVudE93bmVyDnBlbmRpbmcGcmFuJE1BWF9SVU5TX1BFUl9GTFVTSBZjcmVhdGVPd25lchhydW5XaXRoT3duZXIYZGlzcG9zZU93bmVyGGluc2lkZVJlbmRlchB0cmFja2luZxRydW5QZW5kaW5nJGNyZWF0ZUVmZmVjdFJlY29yZBJydW5FZmZlY3QaZGlzcG9zZUVmZmVjdBZ1bnN1YnNjcmliZRZydW5DbGVhbnVwcwp0cmFjawxub3RpZnkOQ09OVFJPTApUaHVuaw5wYXRjaGVzEGhhbmRsZXJzDG5leHRJZBByZXNldElkcwhTbG90GmNhbGxDb21wb25lbnQaY3JlYXRlRWxlbWVudBBiaW5kUHJvcAxzY2FsYXIOZmxhdHRlbhpyZW5kZXJJbk93bmVyEHBlbmRpbmcyEG5leHRDYklkCnF1ZXJ5CGNhbGwIc2VuZAxyZXBvcnQccmVzb2x2ZVBlbmRpbmcacmVqZWN0UGVuZGluZxpjYW5jZWxQZW5kaW5nGGFsbG9jYXRlQ2JJZB5yZWdpc3RlclBlbmRpbmcUc2V0VGltZW91dBhjbGVhclRpbWVvdXQcaW5zdGFsbEdsb2JhbHMIcm9vdA5jdXJyZW50DnZpc2libGUUc2V0VmlzaWJsZQx0b3BpY3MMb25FbWl0DGxpc3Rlbg5ndWFyZGVkDmVudHJpZXMOaW5zdGFsbAZSQVcIS0VZUw5wcm94aWVzFnN1YnNjcmliZXJzFHVud3JhcERlZXAadW53cmFwU2hhbGxvdxZpc1dyYXBwYWJsZQh3cmFwCHN1YnMOb2JzZXJ2ZQ5jaGFuZ2VkDmlzSW5kZXgSaGFuZGxlcnMyIGludGVybmFsX2V4cG9ydHMYX19ob3N0X2FwcGx5GF9faG9zdF9xdWVyeRZfX2hvc3RfY2FsbBZfX2hvc3Rfc2VuZBpfX2hvc3RfcmVwb3J0DlJlZmxlY3QMMC4xMy4wHHRpbnl1aS5jb250cm9sCm1vdW50DGluc2VydAhtb3ZlDHJlbW92ZQxvZmZzZXQMYXNzaWduFGNvbXBvbmVudHMYY2FwYWJpbGl0aWVzDnVubW91bnQQZGlzcGF0Y2gIZW1pdApmbHVzaBR0aW55dWkucmF3FnRpbnl1aS5rZXlzBmFsbA5lZmZlY3RzEGNsZWFudXBzEGRpc3Bvc2VkCm93bmVyBGZuEnByZXZPd25lchRwcmV2RWZmZWN0AmUCYwxzcGxpY2UOcmV2ZXJzZQhpbml0CnN1YnMyAnYOZWZmZWN0MgJtCmRpcnR5CHB1c2hsb25DbGVhbnVwKCkgY2FsbGVkIG91dHNpZGUgYSBzeW5jaHJvbm91cyByZW5kZXIgcGVyaW9kCHByZXYCaQxxdWV1ZWQIcnVuc3x1cGRhdGUgbG9vcDogYW4gZWZmZWN0IHJlLXJhbiBtb3JlIHRoYW4gMTAwIHRpbWVzIGluIG9uZSBmbHVzaGZlZmZlY3QoKSBjYWxsZWQgb3V0c2lkZSBhIHN5bmNocm9ub3VzIHJlbmRlciBwZXJpb2QIZGVwcwxwYXJlbnQQZW50cmllczIQcG9zaXRpb24Kbm9kZXMIbm9kZQRhdAR0bw5pbmRleE9mLG1vdmU6IG5vZGUgbm90IGluIHNsb3QwcmVtb3ZlOiBub2RlIG5vdCBpbiBzbG90AnICbgRpZAZjbWQIYXJnc15yZWYuY21kKCkgYmVmb3JlIHRoZSByZWYgd2FzIGF0dGFjaGVkIHRvIGEgbm9kZQJ4EkZyYWdtZW50Mgpwcm9wcxBjaGlsZHJlbgh0eXBlXGgoKSBjYWxsZWQgb3V0c2lkZSBhIHN5bmNocm9ub3VzIHJlbmRlciBwZXJpb2QCcAZrZXkMcmVzdWx0CHdoYXR8YSBQcm9taXNlIChhc3luYyBjb21wb25lbnRzIGFyZSBub3Qgc3VwcG9ydGVkOyB1c2UgcmVzb3VyY2UoKSkOaXNBcnJheVRzZXZlcmFsIG5vZGVzICh3cmFwIHRoZW0gaW4gb25lIGNvbnRhaW5lcilOYSBGb3IgLyBTaG93ICh3cmFwIGl0IGluIG9uZSBjb250YWluZXIpFGNvbXBvbmVudCAWPGFub255bW91cz5GIG11c3QgcmV0dXJuIGV4YWN0bHkgb25lIG5vZGUsIGdvdCACawpjaGlsZAh0ZXN0AjwCICg+IG11c3QgYmUgYSBmdW5jdGlvbgI6CGxhc3QKZmlyc3QCdFY+IGlzIGEgZnVuY3Rpb247IGRpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgaXQ/qgE+IG11c3QgYmUgYSBzdHJpbmcsIG51bWJlciwgYm9vbGVhbiBvciBudWxsOyBwcm9wcyBkbyBub3QgY3Jvc3MgdGhlIGJyaWRnZSBhcyBvYmplY3RzBm91dAxyZW5kZXI6IG11c3QgcmV0dXJuIGV4YWN0bHkgb25lIG5vZGUIY29kZQ5kZXRhaWxzDmhlYWRlcnMIYm9keRJwYXRjaEpzb24KcGFyc2USc3RyaW5naWZ5CGNiSWQIc2l0ZQhraW5kDGRldGFpbBRyZXN1bHRKc29uFEVfQkFEX0pTT04yaG9zdCByZXN1bHQgaXMgbm90IEpTT046IBJlcnJvckpzb24KZXJyb3IgaG9zdCBjYWxsIGZhaWxlZARtcxx0aW1lci5zY2hlZHVsZRh0aW1lci5jYW5jZWwCZwp0b3BpY2ZvbkVtaXQoKSBjYWxsZWQgb3V0c2lkZSBhIHN5bmNocm9ub3VzIHJlbmRlciBwZXJpb2QKZW50cnkGZXJyBEUxCHBhZ2UScHJvcHNKc29uEGhvc3RKc29uKG1vdW50KCkgY2FsbGVkIHR3aWNlTnBhZ2UgbXVzdCByZXR1cm4gZXhhY3RseSBvbmUgbm9kZSwgZ290IBJhIFByb21pc2UKY2xlYXIMbm9kZUlkCmV2ZW50FnBheWxvYWRKc29uDmhhbmRsZXIOcGF5bG9hZAhqc29uEF9fdGlueXVpWm9ic2VydmFibGUoKSB0YWtlcyBh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", ) val native: Array = arrayOf( diff --git a/compose/src/commonTest/kotlin/app/tinyui/PageHostTest.kt b/compose/src/commonTest/kotlin/app/tinyui/PageHostTest.kt index 8ab9825..55ab2aa 100644 --- a/compose/src/commonTest/kotlin/app/tinyui/PageHostTest.kt +++ b/compose/src/commonTest/kotlin/app/tinyui/PageHostTest.kt @@ -123,7 +123,7 @@ class PageHostTest { val host = host("""{"name":"tinyui"}""") host.start() host.await { host.tree.root.children.isNotEmpty() } - assertEquals("hello tinyui / 17", host.tree.node(1)!!.props["text"]) + assertEquals("hello tinyui / 18", host.tree.node(1)!!.props["text"]) assertNull(host.failure) host.close() } diff --git a/compose/src/commonTest/kotlin/app/tinyui/components/PopoverOffsetTest.kt b/compose/src/commonTest/kotlin/app/tinyui/components/PopoverOffsetTest.kt new file mode 100644 index 0000000..adf786c --- /dev/null +++ b/compose/src/commonTest/kotlin/app/tinyui/components/PopoverOffsetTest.kt @@ -0,0 +1,53 @@ +package app.tinyui.components + +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntRect +import androidx.compose.ui.unit.IntSize +import kotlin.test.Test +import kotlin.test.assertEquals + +class PopoverOffsetTest { + private val window = IntSize(400, 800) + // a field across the middle of the screen, 16 px in from each side + private val field = IntRect(16, 300, 384, 356) + private val card = IntSize(368, 200) + + @Test + fun abovePutsTheBottomEdgeAGapOverTheAnchor() = + assertEquals(IntOffset(16, 92), popoverOffset(field, window, card, above = true, gap = 8, rtl = false)) + + @Test + fun belowPutsTheTopEdgeAGapUnderTheAnchor() = + assertEquals(IntOffset(16, 364), popoverOffset(field, window, card, above = false, gap = 8, rtl = false)) + + @Test + fun flipsWhenThePreferredSideHasNoRoom() { + val nearTop = IntRect(16, 100, 384, 156) + assertEquals(IntOffset(16, 164), popoverOffset(nearTop, window, card, above = true, gap = 8, rtl = false)) + val nearBottom = IntRect(16, 600, 384, 656) + assertEquals(IntOffset(16, 392), popoverOffset(nearBottom, window, card, above = false, gap = 8, rtl = false)) + } + + @Test + fun fitsNeitherSideTakesTheRoomierOneAndStaysInTheWindow() { + val tall = IntSize(368, 500) + // 300 above vs 444 below: below, pushed up so the bottom edge stays on screen + assertEquals(IntOffset(16, 300), popoverOffset(field, window, tall, above = true, gap = 8, rtl = false)) + } + + @Test + fun startEdgesAlignAndNeverLeaveTheWindow() { + val narrow = IntSize(100, 50) + assertEquals(IntOffset(284, 242), popoverOffset(field, window, narrow, above = true, gap = 8, rtl = true)) + val pastRightEdge = IntRect(350, 300, 390, 340) + assertEquals(IntOffset(300, 242), popoverOffset(pastRightEdge, window, narrow, above = true, gap = 8, rtl = false)) + } + + @Test + fun aFullWidthAnchorGetsAFullWidthCardFlushWithTheEdges() { + // Popup measures its content against the window, so the card is never wider than the window + val edgeToEdge = IntRect(0, 300, 400, 356) + assertEquals(IntOffset(0, 92), popoverOffset(edgeToEdge, window, IntSize(400, 200), above = true, gap = 8, rtl = false)) + assertEquals(IntOffset(0, 92), popoverOffset(edgeToEdge, window, IntSize(400, 200), above = true, gap = 8, rtl = true)) + } +} diff --git a/docs/components.md b/docs/components.md index f623a2c..4c506ac 100644 --- a/docs/components.md +++ b/docs/components.md @@ -82,6 +82,7 @@ prop 类型:`string` / `number` / `boolean` / `dp` / `sp` / `color`(`#RRGGBB | `Icon` | `icon`(必填,`icon` 类型)、`size`(dp,默认 24)、`tint`(color,缺省跟随内容色)、`label`(读屏念的名字;紧挨文字的装饰图标不设) | `onClick` | | | | `Loading` | `size`(dp,默认 24)、`color`(缺省 `primary`) | | | | | `BottomSheet` | `open`(必填);不接受布局 prop | `onDismiss` | | 是:弹层的内容 | +| `Popover` | `open`(必填)、`placement`(above / below,默认 below)、`matchAnchorWidth`;不接受布局 prop | `onDismiss`(点了弹层外面) | | 是:卡片的内容 | | `Divider` | `thickness`(dp,默认 1)、`color`(默认 `outlineVariant`) | | | | `RadioButton` 的选中态是普通 prop(2026-09-17 加):它只报点击,选中哪个由 JS 决定——单选组的真值本来就在页面状态里,不属于 ADR-004 的"高频交互状态"。`TextField` 的文本与光标永远在 Kotlin 侧(ADR-004 §3.3):`setText` 会同时触发 `onChange`。`LazyColumn` 的行就是它的 children,虚拟化只在组合层(ADR-003 §3.6)。 @@ -124,6 +125,22 @@ const [open, setOpen] = signal(false); ``` +`Popover` 是锚在父节点上的浮动卡片(2026-10-29 加,注册流程触发:密码框聚焦时在它上方浮出规则清单,盖住上面的内容而不推开布局)。锚点就是父节点,不另设 ref:Compose `Popup` 本来就锚在调用处的父布局上,内置组件渲染 children 也不加包装。所以写法是用 `Box` 把锚元素和它包在一起;直接放进带 `gap` 的 `Column` 会锚到整列,而且它在组合里占一个零尺寸的位置,打开时会多出一份 `gap`。`placement` 是首选的一侧,那一侧放不下就翻到另一侧,两侧都放不下取空间大的一侧;水平方向与锚点起始边对齐,两个方向都不出窗口,页面滚动时跟着锚点走。`matchAnchorWidth` 让卡片与锚点同宽(输入框下的说明),不设就按内容宽(图标按钮旁的提示)。 + +它**永不获取焦点**:锚在聚焦输入框上的提示不能把键盘收走。显隐完全跟 `open`(淡入淡出);点卡片外面只报 `onDismiss`、不自己收起,因为用户刚点的那个输入框也算"外面"——要不要关由页面决定,密码规则这种场景只跟焦点走、不监听它。外观归框架:`surface` 底、`onSurface` 字(显式给出,不靠 `contentColorFor` 从容器色推)、medium 圆角、3dp 阴影;内边距与内容由页面用 children 写。不做:箭头、背景色 prop、左右两侧弹出。 + +```tsx +const [focused, setFocused] = signal(false); + + setFocused(e.focused)} … /> + + … + + +``` + +叫 `Popover` 而不叫 `Tooltip`:M3 里最接近的是 rich tooltip,但 M3 的 tooltip 由框架在长按、悬停时自己触发,偏短文字,宽度上限 320dp;这里是页面掌握开关、内容不限的锚定浮层,与 Web(Radix、MUI 的 `Popover` / `Tooltip` 并存)和 iOS 的 popover 同义。`Tooltip` 这个名字留给将来按 M3 语义实现的那个(图标按钮长按出一句说明)。 + `Divider` 是 M3 `HorizontalDivider`:占满宽度的一条线,缩进用 `paddingHorizontal`(2026-10-12 加,与 Compose 组件对齐;像素上等同 ``,内置是为了写法与默认值跟 M3 走)。不做:竖线(`VerticalDivider` 要靠 `IntrinsicSize` 撑高,框架还没有内在尺寸)与一像素 hairline(尺寸只按 dp 过桥)。 **`Image` 推迟**:牵出图片加载管线的选型(coil3 还是宿主提供 loader),M2 用不到,单独一次定。 diff --git a/packages/core/src/generated/components.ts b/packages/core/src/generated/components.ts index 9e3ed65..71e7822 100644 --- a/packages/core/src/generated/components.ts +++ b/packages/core/src/generated/components.ts @@ -310,6 +310,20 @@ export interface OptionProps { text: string; } +export interface PopoverDismissPayload { +} + +/** Card floating next to its parent, which is the anchor; children are its content. Shown while `open`; it never takes focus, so the keyboard stays up. `onDismiss` reports a tap outside, the page decides whether to close. */ +export interface PopoverProps { + open: boolean; + /** preferred side of the anchor; flips when that side has no room */ + placement?: "above" | "below"; + /** as wide as the anchor instead of its content */ + matchAnchorWidth?: boolean; + onDismiss?: (e: PopoverDismissPayload) => void; + children?: Node | Node[]; +} + export interface IntrinsicElements { Column: ColumnProps; Row: RowProps; @@ -328,6 +342,7 @@ export interface IntrinsicElements { CodeField: CodeFieldProps; Select: SelectProps; Option: OptionProps; + Popover: PopoverProps; } export const Column = "Column"; @@ -347,3 +362,4 @@ export const Checkbox = "Checkbox"; export const CodeField = "CodeField"; export const Select = "Select"; export const Option = "Option"; +export const Popover = "Popover"; diff --git a/sample/js-extra/src/pages/form.tsx b/sample/js-extra/src/pages/form.tsx index 93e4f63..0ab6b49 100644 --- a/sample/js-extra/src/pages/form.tsx +++ b/sample/js-extra/src/pages/form.tsx @@ -1,12 +1,13 @@ -import { Button, Checkbox, CodeField, Column, Option, ref, Row, Select, signal, Text, TextField, type CodeFieldCommands } from "tinyui-core"; +import { Box, Button, Checkbox, CodeField, Column, Icon, Option, Popover, ref, Row, Select, signal, Text, TextField, type CodeFieldCommands } from "tinyui-core"; import { crypto, ui } from "tinyui-native"; import visibility from "@material-symbols/svg-400/outlined/visibility.svg"; import visibilityOff from "@material-symbols/svg-400/outlined/visibility_off.svg"; +import check from "@material-symbols/svg-400/outlined/check.svg"; // a throwaway demo key; a real page fetches its server's key over its channel const DEMO_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1h+fpBuEFQRG4A5eKK2zLAc9a2+gKiLeKfbQxYAe8/ty4avmzchM9s5C7wbCGpvPu6ptU4IXNKWv9tjDAZdAW79uYhaLBIXARR4xUBbUTBicFIVCUTEoByaTDuqXnavkg4OoE5iSGqqq0klRMBtloKQ42V70epl89PTwlYEYp6MHGLAwNx2G95SufWoXca6AWZmxjWwIvImwpIN51mMjTXv8JLv5apwf6SitQwAwp4xnibb4Rlt4SpgbKFDBylCkfxuNXJ4TBExYC17/90+j6w8FMYs/IFfBPVS0MyAnV/jd5IcLmPMGBDHLl/ODhvn4lqO1XJ0fVikqR9Rj2skzwIDAQAB"; -/** The form pieces a sign-up flow needs: checkbox, field adornments, code cells, dropdown, inline links, RSA. */ +/** The form pieces a sign-up flow needs: checkbox, field adornments, rule popover, code cells, dropdown, inline links, RSA. */ export default function Form() { const [email, setEmail] = signal(""); const [password, setPassword] = signal(""); @@ -30,12 +31,21 @@ export default function Form() { error={emailError()} supportingText={emailError() ? "Not an email address" : ""} onChange={(e) => setEmail(e.text)} /> - setShown(!shown())} - supportingText={focused() ? "8+ characters, letters and digits" : ""} - onFocusChange={(e) => setFocused(e.focused)} onChange={(e) => setPassword(e.text)} - /> + + setShown(!shown())} + onFocusChange={(e) => setFocused(e.focused)} onChange={(e) => setPassword(e.text)} + /> + {/* the rules float over whatever is above the field while it has focus; typing ticks them off */} + + + + = 8} text="At least 8 characters" /> + + + +