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
8 changes: 6 additions & 2 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<!-- AndroidX core / activity / lifecycle -->
<PackageReference Update="Xamarin.AndroidX.Activity" Version="1.13.0" />
<PackageReference Update="Xamarin.AndroidX.Activity.Compose" Version="1.13.0" />
<PackageReference Update="Xamarin.AndroidX.Core" Version="1.19.0" />
<PackageReference Update="Xamarin.AndroidX.Core.Core.Ktx" Version="1.19.0" />
<PackageReference Update="Xamarin.AndroidX.Lifecycle.Runtime.Compose" Version="2.10.0.2" />
<PackageReference Update="Xamarin.AndroidX.Lifecycle.Runtime.Compose.Android" Version="2.10.0.3" />

Expand All @@ -30,12 +32,14 @@
<PackageReference Update="Xamarin.AndroidX.Compose.Animation.Android" Version="1.11.2.1" />
<PackageReference Update="Xamarin.AndroidX.Compose.Animation.Core" Version="1.11.2" />
<PackageReference Update="Xamarin.AndroidX.Compose.Animation.Core.Android" Version="1.11.2.1" />
<PackageReference Update="Xamarin.AndroidX.Compose.Foundation" Version="1.11.2.1" />
<PackageReference Update="Xamarin.AndroidX.Compose.Foundation.Android" Version="1.11.2.1" />
<PackageReference Update="Xamarin.AndroidX.Compose.Foundation" Version="1.11.2.2" />
<PackageReference Update="Xamarin.AndroidX.Compose.Foundation.Android" Version="1.11.2.2" />
<PackageReference Update="Xamarin.AndroidX.Compose.Foundation.Layout" Version="1.11.2" />
<PackageReference Update="Xamarin.AndroidX.Compose.Foundation.Layout.Android" Version="1.11.2" />
<PackageReference Update="Xamarin.AndroidX.Compose.Material3" Version="1.4.0.2" />
<PackageReference Update="Xamarin.AndroidX.Compose.Material3Android" Version="1.4.0.3" />
<PackageReference Update="Xamarin.AndroidX.Compose.Material3.Adaptive" Version="1.2.0" />
<PackageReference Update="Xamarin.AndroidX.Compose.Material3.AdaptiveAndroid" Version="1.2.0" />
<PackageReference Update="Xamarin.AndroidX.Compose.Material.Icons.Core" Version="1.7.8.6" />
<PackageReference Update="Xamarin.AndroidX.Compose.Material.Icons.Core.Android" Version="1.7.8.6" />
<PackageReference Update="Xamarin.AndroidX.Compose.Runtime" Version="1.11.2.1" />
Expand Down
2 changes: 1 addition & 1 deletion samples/JetNews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ feature.

| Upstream feature | Tracking issue |
|-----------------------------------------------------------------|----------------|
| Adaptive list-detail two-pane layout on wider devices | [#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143) (WindowSizeClass), plus a SharedTransitionLayout / ListDetailScene binding |
| Adaptive list-detail two-pane layout on wider devices | `SharedTransitionLayout` / `ListDetailScene` binding (the `WindowSizeClass` read itself shipped in [#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143) — see `composer.CurrentWindowAdaptiveInfo()`) |
| Real hero PNGs in card / article (currently a solid `Box` filled with a per-post `HeroColor`) | [#145](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/145) — `ContentScale.Crop` on the `Image` facade; without it small vector hero images letterbox |
| Inline-run paragraph styling (Link / Bold / Italic / Code spans inside one paragraph) | [#141](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/141) — `AnnotatedString` + `SpanStyle` |
| Top-bar elevation / collapse on scroll (`pinnedScrollBehavior`, `enterAlwaysScrollBehavior`) | [#142](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/142) — `Modifier.nestedScroll` + `TopAppBarDefaults` |
Expand Down
4 changes: 2 additions & 2 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ that needs the same primitive.
| [#20](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/20) | Edge-to-edge bootstrapping | Status/nav-bar overlap on every sample. |
| [#141](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/141) | `AnnotatedString` + `SpanStyle` for inline-run text styling | Link / Bold / Italic / Code spans inside paragraphs in **JetNews** article reader. |
| [#142](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/142) | `Modifier.nestedScroll` + `TopAppBarDefaults` scroll behaviors | Top-bar elevation / collapse on scroll in **JetNews**, **Reply**, **Jetcaster**. |
| [#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143) | WindowSizeClass / `currentWindowAdaptiveInfo` | Adaptive layouts; blocks **Reply** entirely and the **JetNews** list-detail screen. |
| [#144](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/144) | Custom `Layout {}` primitive — Measurable / Placeable / MeasureScope | `InterestsAdaptiveContentLayout` in **JetNews**, custom carousels in **Jetsnack**, asymmetric chat bubbles in **Jetchat**. |
| [#145](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/145) | `ContentScale` + `Alignment` slots on the `Image` facade | Hero images on cards in **JetNews** (currently solid-color `Box` placeholders). |
| [#146](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/146) | `stringResource(id)` lookup | Localizable UI strings in every sample (all currently inline literals). |
Expand All @@ -66,7 +65,8 @@ Closed gaps that previously appeared here (now usable in samples):
**#63** Modifier surface (Background/Border/Clickable/Size/Width/Height/AspectRatio/Offset/Alpha/Clip/Weight + scroll + focus + semantics + Draggable),
**#65** Compose value types (`Color`/`Dp`/`Sp`/`FontWeight`/`TextAlign`),
**#70** Row/Column `Arrangement`,
**#140** `DrawerState.open()` / `close()` suspend bridges.
**#140** `DrawerState.open()` / `close()` suspend bridges,
**#143** `WindowSizeClass` predicates + `currentWindowAdaptiveInfo()` extension (NavigationSuiteScaffold, SharedTransitionLayout, and ListDetailScene bindings still missing — see [#168](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/168) for the fold-aware TwoPane piece).

## Attribution

Expand Down
4 changes: 2 additions & 2 deletions samples/Reply/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ links back to the tracking issues.

| Upstream feature | Status | Tracking issue |
|------------------|--------|----------------|
| `NavigationSuiteScaffold` + `WindowSizeClass` (compact → medium → expanded switchover) | dropped — pinned to bottom nav | [#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143) |
| `NavigationRail` / `PermanentNavigationDrawer` / `ModalNavigationDrawer` content for medium and expanded sizes | dropped — bottom nav only | [#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143) |
| `NavigationSuiteScaffold` (compact → medium → expanded switchover) | dropped — pinned to bottom nav | `Xamarin.AndroidX.Compose.Material3.Adaptive.NavigationSuite` not yet referenced; would also need [#163](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/163). The size-class read itself ([#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143)) shipped — see `composer.CurrentWindowAdaptiveInfo()`. |
| `NavigationRail` / `PermanentNavigationDrawer` / `ModalNavigationDrawer` content for medium and expanded sizes | dropped — bottom nav only | [#163](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/163) (drawer-row facade) — branching on `WindowSizeClass` is unblocked by [#143](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/143). |
| `accompanist.adaptive.TwoPane` + `WindowLayoutInfo`/`FoldingFeature` (list-detail with fold avoidance) | dropped — single-pane | [#168](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/168) |
| `NavigationDrawerItem` rows inside `ModalDrawerSheet` | not used (no drawer in single-pane port) | [#163](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/163) |
| `BackHandler {}` to collapse multi-select / detail | dropped — system back falls through to the navigator | [#166](https://github.com/jonathanpeppers/Microsoft.AndroidX.Compose/issues/166) |
Expand Down
9 changes: 7 additions & 2 deletions samples/Reply/ReplyApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ namespace AndroidX.Compose.Samples.Reply;
/// <remarks>
/// Upstream Reply uses <c>NavigationSuiteScaffoldLayout</c> +
/// <c>WindowSizeClass</c> to pick between bottom nav (compact), nav
/// rail (medium), and permanent drawer (expanded). That adaptive
/// scaffold isn't bound yet (#143), so this port pins to bottom nav.
/// rail (medium), and permanent drawer (expanded). The
/// <c>WindowSizeClass</c> read itself is now available (issue #143 —
/// see <c>composer.CurrentWindowAdaptiveInfo()</c>), but
/// <c>NavigationSuiteScaffold</c> lives in the
/// <c>Xamarin.AndroidX.Compose.Material3.Adaptive.NavigationSuite</c>
/// package which isn't referenced yet, so this port still pins to
/// bottom nav.
/// </remarks>
public static class ReplyApp
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using AndroidX.Compose.Runtime;
using AndroidX.Compose.Gallery.Registry;
using AndroidX.Window.Core.Layout;

namespace AndroidX.Compose.Gallery.Demos.LocalsMisc;

/// <summary>
/// <c>composer.CurrentWindowAdaptiveInfo()</c> — live readout of the upstream
/// <see cref="WindowSizeClass"/> + <c>Posture</c>, plus a phone / tablet / desktop
/// indicator that flips at the Material 3 standard breakpoints. Rotate the
/// device or resize the split-screen window to see all values update.
/// </summary>
public static class WindowSizeClassDemo
{
/// <summary>Registry entry exposed via <see cref="Catalog.Demos"/>.</summary>
public static Demo Demo => new(
Id: "locals-window-size-class",
CategoryId: "locals-misc",
Title: "WindowAdaptiveInfo & WindowSizeClass",
Description: "composer.CurrentWindowAdaptiveInfo() — live size class predicates + posture for adaptive layouts. Rotate to flip the Phone/Tablet/Desktop label.",
Build: _ => new Column
{
new SizeClassReadout(),
});

sealed class SizeClassReadout : ComposableNode
{
public override void Render(IComposer composer)
{
var info = composer.CurrentWindowAdaptiveInfo();
var size = info.WindowSizeClass;
var posture = info.WindowPosture;

new Column
{
new Text($"MinWidthDp = {size.MinWidthDp}"),
new Text($"MinHeightDp = {size.MinHeightDp}"),
new Text(""),
new Text("Width predicates at standard breakpoints:"),
new Text($" IsWidthAtLeastBreakpoint(600) = {size.IsWidthAtLeastBreakpoint(WindowSizeClass.WidthDpMediumLowerBound)}"),
new Text($" IsWidthAtLeastBreakpoint(840) = {size.IsWidthAtLeastBreakpoint(WindowSizeClass.WidthDpExpandedLowerBound)}"),
new Text("Height predicates at standard breakpoints:"),
new Text($" IsHeightAtLeastBreakpoint(480) = {size.IsHeightAtLeastBreakpoint(WindowSizeClass.HeightDpMediumLowerBound)}"),
new Text($" IsHeightAtLeastBreakpoint(900) = {size.IsHeightAtLeastBreakpoint(WindowSizeClass.HeightDpExpandedLowerBound)}"),
new Text(""),
new Text($"Layout class: {DeviceLabel(size)}"),
new Text(""),
new Text("Posture (foldable / hinge state):"),
new Text($" IsTabletop = {posture.IsTabletop}"),
new Text($" Hinge count = {posture.HingeList.Count}"),
}.Render(composer);
}

// Process larger breakpoints first — IsWidthAtLeastBreakpoint is order-
// dependent: a 1200dp window matches the 600dp breakpoint too. Upstream
// docs explicitly call out this larger→smaller ordering.
static string DeviceLabel(WindowSizeClass size) =>
size.IsWidthAtLeastBreakpoint(WindowSizeClass.WidthDpExpandedLowerBound) ? "🖥️ Desktop (Expanded)" :
size.IsWidthAtLeastBreakpoint(WindowSizeClass.WidthDpMediumLowerBound) ? "📟 Tablet (Medium)" :
"📱 Phone (Compact)";
}
}
1 change: 1 addition & 0 deletions src/Microsoft.AndroidX.Compose.Gallery/Registry/Catalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public static class Catalog
D.LocalsMisc.BuiltInCompositionLocalsDemo.Demo,
D.LocalsMisc.CustomCompositionLocalDemo.Demo,
D.LocalsMisc.ComposeViewInteropDemo.Demo,
D.LocalsMisc.WindowSizeClassDemo.Demo,
D.LocalsMisc.CircularProgressIndicatorDemo.Demo,
D.LocalsMisc.LinearProgressIndicatorDemo.Demo,
D.LocalsMisc.ImageDemo.Demo,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using AndroidX.Compose.Material3.Adaptive;
using AndroidX.Compose.Runtime;

namespace AndroidX.Compose;

public static partial class ComposeExtensions
{
/// <summary>
/// C# parity of Kotlin's <c>currentWindowAdaptiveInfo()</c> <c>@Composable</c>
/// from <c>androidx.compose.material3.adaptive</c>. Returns the live
/// <see cref="WindowAdaptiveInfo"/> for the host window — exposes both the
/// upstream <see cref="AndroidX.Window.Core.Layout.WindowSizeClass"/>
/// (with <c>IsWidthAtLeastBreakpoint</c> / <c>IsHeightAtLeastBreakpoint</c>
/// + the standard 600 / 840 / 480 / 900 dp breakpoint constants) and the
/// <see cref="Posture"/> describing foldable / tabletop state.
///
/// <para>Use this to branch between phone / tablet / desktop layouts inside
/// a composable:</para>
///
/// <code>
/// var info = composer.CurrentWindowAdaptiveInfo();
/// if (info.WindowSizeClass.IsWidthAtLeastBreakpoint(
/// AndroidX.Window.Core.Layout.WindowSizeClass.WidthDpMediumLowerBound))
/// return ListDetailScreen.Build(...);
/// else
/// return PhoneScreen.Build(...);
/// </code>
///
/// <para>Re-reads on every recomposition Compose drives, so layout code
/// that branches off the returned <see cref="WindowAdaptiveInfo"/> reacts
/// naturally to rotation, multi-window resize, fold / unfold, and
/// activity-embedded surface changes.</para>
/// </summary>
/// <param name="composer">The composer for the active composition.</param>
/// <param name="supportLargeAndXLargeWidth">
/// When <c>true</c>, snaps width buckets at the additional <c>1200</c> dp
/// (large) and <c>1600</c> dp (extra-large) breakpoints in addition to the
/// standard <c>600</c> / <c>840</c> bounds. Mirrors the Kotlin parameter
/// of the same name; defaults to <c>false</c> for parity with the
/// no-argument Kotlin call site.
/// </param>
/// <returns>
/// The bound <see cref="WindowAdaptiveInfo"/> Kotlin would have returned —
/// not a managed wrapper. Pass it straight to any binding API that takes
/// one (e.g. <c>NavigationSuiteScaffold</c>).
/// </returns>
public static WindowAdaptiveInfo CurrentWindowAdaptiveInfo(
this IComposer composer,
bool supportLargeAndXLargeWidth = false)
{
ArgumentNullException.ThrowIfNull(composer);

return WindowAdaptiveInfoKt.CurrentWindowAdaptiveInfo(
supportLargeAndXLargeWidth,
composer,
p2: 0,
_changed: 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
<ItemGroup>
<PackageReference Include="Xamarin.AndroidX.Activity" />
<PackageReference Include="Xamarin.AndroidX.Activity.Compose" />
<PackageReference Include="Xamarin.AndroidX.Core" />
<PackageReference Include="Xamarin.AndroidX.Core.Core.Ktx" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime.Compose" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.Runtime.Compose.Android" />
<PackageReference Include="Xamarin.AndroidX.Compose.Animation" />
Expand All @@ -58,6 +60,8 @@
<PackageReference Include="Xamarin.AndroidX.Compose.Foundation.Layout.Android" />
<PackageReference Include="Xamarin.AndroidX.Compose.Material3" />
<PackageReference Include="Xamarin.AndroidX.Compose.Material3Android" />
<PackageReference Include="Xamarin.AndroidX.Compose.Material3.Adaptive" />
<PackageReference Include="Xamarin.AndroidX.Compose.Material3.AdaptiveAndroid" />
<PackageReference Include="Xamarin.AndroidX.Compose.Material.Icons.Core" />
<PackageReference Include="Xamarin.AndroidX.Compose.Material.Icons.Core.Android" />
<PackageReference Include="Xamarin.AndroidX.Navigation.Common" />
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.AndroidX.Compose/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,7 @@ static AndroidX.Compose.ComposeExtensions.CollectAsStateWithLifecycle<T>(this Xa
static AndroidX.Compose.ComposeExtensions.CollectAsStateWithLifecycle<T>(this Xamarin.KotlinX.Coroutines.Flow.IStateFlow! stateFlow, AndroidX.Compose.Runtime.IComposer! composer) -> AndroidX.Compose.CollectedState<T>!
static AndroidX.Compose.ComposeExtensions.ColorResource(this AndroidX.Compose.Runtime.IComposer! composer, int id) -> long
static AndroidX.Compose.ComposeExtensions.ColorScheme(this AndroidX.Compose.Runtime.IComposer! composer) -> AndroidX.Compose.Material3.ColorScheme!
static AndroidX.Compose.ComposeExtensions.CurrentWindowAdaptiveInfo(this AndroidX.Compose.Runtime.IComposer! composer, bool supportLargeAndXLargeWidth = false) -> AndroidX.Compose.Material3.Adaptive.WindowAdaptiveInfo!
static AndroidX.Compose.ComposeExtensions.DerivedStateOf<T>(System.Func<T>! calculation) -> AndroidX.Compose.DerivedState<T>!
static AndroidX.Compose.ComposeExtensions.DerivedStateOf<T>(this AndroidX.Compose.Runtime.IComposer! composer, System.Func<T>! calculation) -> AndroidX.Compose.DerivedState<T>!
static AndroidX.Compose.ComposeExtensions.DimensionResource(this AndroidX.Compose.Runtime.IComposer! composer, int id) -> AndroidX.Compose.Dp
Expand Down
Loading