Skip to content

Compose Material3: DateInput / DateRangeInput / SearchBar / DropdownMenu / ExposedDropdownMenu @Composables not bound (all Kt wrappers are empty) #1447

@jonathanpeppers

Description

@jonathanpeppers

Summary

Several user-facing @Composables in androidx.compose.material3 are unreachable from C# because their Kt wrapper classes bind as empty containers with zero static method members. Specifically:

  • DateInputKt.DateInput(...) — alternative typed-entry mode for the date picker
  • DateRangeInputKt.DateRangeInput(...) — alternative typed-entry mode for the date-range picker
  • SearchBarKt.SearchBar(...) — the recommended Material 3 search bar pattern (along with its DockedSearchBar, SearchBarDefaults.InputField, etc.)
  • SearchBar_androidKt.SearchBar(...) — the Android-specific overloads
  • AndroidMenu_androidKt.DropdownMenu(...) / .DropdownMenuItem(...) — the standard dropdown menu primitives
  • ExposedDropdownMenuKt.* / ExposedDropdownMenu_androidKt.* — text-field-anchored dropdown (the "ExposedDropdownMenuBox" + content pattern)

The state-holder classes (e.g. DatePickerState, DateRangePickerState, SearchBarState, MenuPosition, ExposedDropdownMenuBoxScope) and the *Defaults companion objects largely are bound — so the type system is there, but every @Composable factory function is dropped.

Library / NuGet

Verified state today (commit eb2f50b)

source/androidx.compose.material3/material3-android/PublicAPI/PublicAPI.Unshipped.txt (171KB) contains all the following as empty wrapper classes — declaration line plus the JniPeerMembers override, but zero static methods:

AndroidX.Compose.Material3.DateInputKt
AndroidX.Compose.Material3.DateRangeInputKt
AndroidX.Compose.Material3.SearchBarKt
AndroidX.Compose.Material3.SearchBar_androidKt
AndroidX.Compose.Material3.AndroidMenu_androidKt
AndroidX.Compose.Material3.ExposedDropdownMenuKt
AndroidX.Compose.Material3.ExposedDropdownMenu_androidKt
AndroidX.Compose.Material3.DatePickerKt
AndroidX.Compose.Material3.DateRangePickerKt
AndroidX.Compose.Material3.DatePickerDialogKt
AndroidX.Compose.Material3.TimePickerKt

(For reference, the same shape applies to ButtonKt, CardKt, TextFieldKt, etc. — the entire @Composable surface of material3 has this problem; this issue is scoped to the picker / search / menu subset because those state-holder types are otherwise reasonably complete, making the gap especially visible.)

Kotlin signatures of the missing methods (illustrative):

@Composable @ExperimentalMaterial3Api
fun DateInput(state: DatePickerState, modifier: Modifier = Modifier, dateFormatter: DatePickerFormatter = …, dateValidator: (Long) -> Boolean = { true }, title: (@Composable () -> Unit)? = …, headline: @Composable () -> Unit = …, colors: DatePickerColors = …)

@Composable @ExperimentalMaterial3Api
fun SearchBar(inputField: @Composable () -> Unit, expanded: Boolean, onExpandedChange: (Boolean) -> Unit, modifier: Modifier = Modifier, shape: Shape = …, colors: SearchBarColors = …, tonalElevation: Dp = …, shadowElevation: Dp = …, windowInsets: WindowInsets = …, content: @Composable ColumnScope.() -> Unit)

@Composable
fun DropdownMenu(expanded: Boolean, onDismissRequest: () -> Unit, modifier: Modifier = Modifier, offset: DpOffset = …, scrollState: ScrollState = …, properties: PopupProperties = …, shape: Shape = …, containerColor: Color = …, tonalElevation: Dp = …, shadowElevation: Dp = …, border: BorderStroke? = …, content: @Composable ColumnScope.() -> Unit)

Every one of these carries at least one @JvmInline value class parameter (Modifier, Dp, Color, Shape, DpOffset), so the JVM signatures get hash-mangled (DateInput--4{hash}, SearchBar-{hash}, DropdownMenu-{hash}, etc.) and the binder drops them.

Metadata.xml today

source/androidx.compose.material3/material3-android/Transforms/Metadata.xml contains only one strip (MaterialTheme.getMotionScheme); none of the picker / search / menu @Composables are mentioned. They are dropped automatically by the binder due to inline-class mangling.

Reproduction / evidence

compose-net works around the search and menu cases with hand-written JNI bridges:

  • [ComposeBridge(Class = "androidx/compose/material3/SearchBarKt", JvmName = "SearchBar-…", …)]
  • [ComposeBridge(Class = "androidx/compose/material3/AndroidMenu_androidKt", JvmName = "DropdownMenu-…", …)]
  • See src/ComposeNet.Compose/ComposeBridges.cs

These bridges call successfully at runtime, confirming the Java methods exist and behave correctly — only the binding-time projection drops them. compose-net's tracking issue for this group is jonathanpeppers/compose-net#4.

For DateInput / DateRangeInput, compose-net's DatePicker / DateRangePicker facades only call the DatePickerKt.DatePicker-... / DateRangePickerKt.DateRangePicker-... bridges today — the typed-input alternative modes are not yet wired up because the underlying methods would need additional bridges.

Suggested fix

This is a downstream effect of dotnet/java-interop#1440. When that PR ships and the binder stops dropping @JvmInline value class overloads with mangled names, every method on DateInputKt, DateRangeInputKt, SearchBarKt, SearchBar_androidKt, AndroidMenu_androidKt, ExposedDropdownMenuKt, and ExposedDropdownMenu_androidKt should bind automatically.

This issue is filed primarily as a tracking issue so the regression in user-facing material3 surface is visible. No action is needed in the android-libraries repo itself until #1440 lands; at that point a re-binding pass should confirm the methods appear.

Cross-references

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions