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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/api-migrations.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# LUI API migration guide

## Unreleased: independent flex shrink on Web and MyGo

`row`, `column` and `box` accept `?shrink:float`. The typed `ShrinkValue`
property uses wire name `shrink` and accepts only finite, nonnegative floats.
Only these three standard kinds admit it. Web maps it to CSS `flex-shrink`;
MyGo uses the existing `Element.Shrink` without an SDK or dependency update.
Generic, SwiftUI and Kotlin profiles reject explicit shrink values; Apple and
Android also reject direct standard wire patches rather than ignoring them.
Extensions/raw markup do not gain a shrink property or escape hatch.

Omitting or removing shrink preserves/restores the existing default factor 1.
Setting or removing it does not change `grow` or flex basis. Existing callers
need no changes. New callers must use a host supporting this property and a
LUI version that knows the new wire name; older hosts reject that opt-in.

For a bounded, clipped single-line strip, opt in on each direct pill container:

```ocaml
row ~flex_wrap:`nowrap
[row ~shrink:0. [text ~value:"First" []];
row ~shrink:0. [text ~value:"Second" []]]
```

Use the existing typed overflow property on the strip for clipping. Shrink on
the strip itself does not disable shrinking its children. Remove unnecessary
child `grow` props to keep intrinsic sizing; do not substitute `grow:0` for
`shrink:0`, because MyGo's `Grow` also changes an auto basis to zero percent.

## Unreleased: opt-in container focus-within observation (Web and MyGo)

`row`, `column` and `box` accept `?on_focus_within:(bool -> unit)` on
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ internal object LuiKindRules {
* op is admissible for the node's kind. */
fun supports(kind: LuiNodeKind, property: String, value: LuiWireValue): Boolean {
if (property == "focus-within-enabled") return false
if (property == "shrink") return false
when (property) {
"virtual-total-count", "virtual-generation", "virtual-indices", "virtual-scroll-index" ->
return kind == LuiNodeKind.virtualList && schemaValueSupported(property, value)
Expand Down
7 changes: 4 additions & 3 deletions platform/android/lui/src/main/kotlin/dev/lui/LuiWireSchema.kt
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ enum class LuiProperty(val wireName: String) {
indeterminate("indeterminate"),
toggleDetailEnabled("toggle-detail-enabled"),
focusWithinEnabled("focus-within-enabled"),
shrink("shrink"),
;

companion object {
Expand Down Expand Up @@ -338,13 +339,13 @@ object LuiSchemaMatrix {
LuiNodeKind.checkbox to setOf(LuiProperty.gap, LuiProperty.labelOpacity, LuiProperty.indicatorBorderColor, LuiProperty.checkedIndicatorBorderColor),
LuiNodeKind.radio to setOf(LuiProperty.gap, LuiProperty.labelOpacity),
LuiNodeKind.grid to setOf(LuiProperty.main, LuiProperty.cross),
LuiNodeKind.row to setOf(LuiProperty.orientation, LuiProperty.focusWithinEnabled),
LuiNodeKind.column to setOf(LuiProperty.focusWithinEnabled),
LuiNodeKind.row to setOf(LuiProperty.orientation, LuiProperty.focusWithinEnabled, LuiProperty.shrink),
LuiNodeKind.column to setOf(LuiProperty.focusWithinEnabled, LuiProperty.shrink),
LuiNodeKind.listItem to setOf(LuiProperty.display),
LuiNodeKind.dialog to setOf(LuiProperty.description, LuiProperty.background, LuiProperty.foreground, LuiProperty.borderColor, LuiProperty.borderWidth, LuiProperty.cornerRadius, LuiProperty.gap, LuiProperty.transition),
LuiNodeKind.drawer to setOf(LuiProperty.transition),
LuiNodeKind.sheet to setOf(LuiProperty.transition),
LuiNodeKind.box to setOf(LuiProperty.inert, LuiProperty.focusWithinEnabled),
LuiNodeKind.box to setOf(LuiProperty.inert, LuiProperty.focusWithinEnabled, LuiProperty.shrink),
LuiNodeKind.popover to setOf(LuiProperty.collisionPadding),
LuiNodeKind.dropdownMenu to setOf(LuiProperty.collisionPadding),
LuiNodeKind.tooltip to setOf(LuiProperty.collisionPadding),
Expand Down
4 changes: 4 additions & 0 deletions platform/apple/Sources/LUIAppleBackend/LUIWireProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ enum LUIWireValue: Decodable, Equatable {
case .grow:
guard let value = doubleValue else { return false }
return value.isFinite && value >= 0
case .shrink:
return false
case .edge:
guard let value = stringValue else { return false }
return Self.edges.contains(value)
Expand Down Expand Up @@ -1089,6 +1091,7 @@ struct LUIRetainedTree {

private static func supports(_ property: LUIProperty, on kind: LUINodeKind) -> Bool {
if property == .focusWithinEnabled { return false }
if property == .shrink { return false }
switch property {
case .virtualTotalCount, .virtualGeneration, .virtualIndices, .virtualScrollIndex:
return kind == .virtualList
Expand Down Expand Up @@ -1124,6 +1127,7 @@ struct LUIRetainedTree {
kind == .popover || kind == .link ||
isHorizontalGroup(kind)
case .grow: kind != .avatar && kind != .tooltip && !isModalSurface(kind)
case .shrink: false
case .columns: kind == .grid
case .gridColumnSpan:
kind != .root && kind != .dialog && kind != .drawer && kind != .sheet
Expand Down
7 changes: 4 additions & 3 deletions platform/apple/Sources/LUIAppleBackend/LUIWireSchema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ enum LUIProperty: String, Decodable, Hashable {
case indeterminate = "indeterminate"
case toggleDetailEnabled = "toggle-detail-enabled"
case focusWithinEnabled = "focus-within-enabled"
case shrink = "shrink"
}

enum LUISchemaMatrix {
Expand Down Expand Up @@ -318,13 +319,13 @@ enum LUISchemaMatrix {
.checkbox: [.gap, .labelOpacity, .indicatorBorderColor, .checkedIndicatorBorderColor],
.radio: [.gap, .labelOpacity],
.grid: [.main, .cross],
.row: [.orientation, .focusWithinEnabled],
.column: [.focusWithinEnabled],
.row: [.orientation, .focusWithinEnabled, .shrink],
.column: [.focusWithinEnabled, .shrink],
.listItem: [.display],
.dialog: [.description, .background, .foreground, .borderColor, .borderWidth, .cornerRadius, .gap, .transition],
.drawer: [.transition],
.sheet: [.transition],
.box: [.inert, .focusWithinEnabled],
.box: [.inert, .focusWithinEnabled, .shrink],
.popover: [.collisionPadding],
.dropdownMenu: [.collisionPadding],
.tooltip: [.collisionPadding],
Expand Down
7 changes: 4 additions & 3 deletions platform/mygo/SUPPORT.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions platform/mygo/capabilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@
"extensions_test.go:TestLayoutGeometry",
"layout_test.go:TestLayoutSharedTypographyAndSpacingRestoreInheritedValues"
],
"contractHash": "5b37ca2312b59c73d5ca14e59389ed49a11b1dc3710bdee1409ce9675f9d8c50"
"contractHash": "2b0005ed2f3e54d3678748d9eb0a731c4ad075ae07bddb12fc87d58413bfb99f"
},
"column": {
"route": "render.go; style.go",
"evidence": [
"extensions_test.go:TestLayoutGeometry",
"layout_test.go:TestLayoutSharedTypographyAndSpacingRestoreInheritedValues"
],
"contractHash": "6f35e51043ab8ae815796b2dd3a147f0a5e01b0fe15b9bab93f588710264f720"
"contractHash": "e1c4ba75a65b5346c3a0231c00d01f0ebaffd12eba823b625f75aa77c36e0bf8"
},
"grid": {
"route": "render.go; style.go",
Expand Down Expand Up @@ -117,7 +117,7 @@
"style_test.go:TestLayoutStyleViewportFractionsAndContainerFrameRemoval",
"style_test.go:TestLayoutStyleShadowOpacityStatesAndRemoval"
],
"contractHash": "028237d9cea015c951093e45aa35dc7c3493f8a22f27106e43dfc506da741866"
"contractHash": "f5ed3d53bdef46b4bf03eef8188877933fa0c005203581850747ecd1423f2c49"
},
"text": {
"route": "render.go; style.go",
Expand Down Expand Up @@ -2338,6 +2338,12 @@
"evidence": [
"controls_test.go:TestControlsCheckboxMixedDetail"
]
},
"shrink": {
"route": "style.go; MyGo Element.Shrink",
"evidence": [
"style_test.go:TestLayoutStyleViewportFractionsAndContainerFrameRemoval"
]
}
},
"events": {
Expand Down
Loading
Loading