$npx -y skills add hanamizuki/solopreneur --skill edge-to-edgeUse this skill to migrate your Jetpack Compose app to add adaptive edge-to-edge
| 1 | ## Prerequisites |
| 2 | |
| 3 | - Project **MUST** use Android Jetpack Compose. |
| 4 | - Project **MUST** target SDK 35 or later. If the SDK is lower than 35, increase the SDK to 35. |
| 5 | |
| 6 | ## Step 1: plan |
| 7 | |
| 8 | 1. Locate and analyze all Activity classes to detect which have existing edge-to-edge support. For every Activity without edge-to-edge, plan to make each Activity edge-to-edge. |
| 9 | 2. In each Activity, Locate and analyze all lists and FAB components to detect which have existing edge-to-edge support. For every component without edge-to-edge support, plan to make each of these components edge-to-edge. |
| 10 | 3. In each Activity, scan for `TextField`, `OutlinedTextField`, or `BasicTextField`. If found, then you **MUST** verify the IME doesn't hide the input field by following the IME section of this skill. |
| 11 | |
| 12 | ## Step 2: add edge-to-edge support |
| 13 | |
| 14 | 1. Add `enableEdgeToEdge` before `setContent` in `onCreate` in each Activity that does not already call `enableEdgeToEdge`. |
| 15 | 2. Add `android:windowSoftInputMode="adjustResize"` in the AndroidManifest.xml for all Activities that use a soft keyboard. |
| 16 | |
| 17 | ## Step 3: apply insets |
| 18 | |
| 19 | - The app **MUST** apply system insets, or align content to rulers, so critical |
| 20 | UI remains tappable. Choose only one method to avoid double padding: |
| 21 | |
| 22 | 1. **PREFERRED:** When available, use `Scaffold`s and pass `PaddingValues` to the content lambda. |
| 23 | |
| 24 | |
| 25 | ```kotlin |
| 26 | Scaffold { innerPadding -> |
| 27 | // innerPadding accounts for system bars and any Scaffold components |
| 28 | LazyColumn( |
| 29 | modifier = Modifier |
| 30 | .fillMaxSize() |
| 31 | .consumeWindowInsets(innerPadding), |
| 32 | contentPadding = innerPadding |
| 33 | ) { /* Content */ } |
| 34 | } |
| 35 | ``` |
| 36 | |
| 37 | <br /> |
| 38 | |
| 39 | 1. **PREFERRED:** When available, use the automatic inset handling or padding modifiers in material components. |
| 40 | |
| 41 | - Material 3 Components manages safe areas for its own components, including: |
| 42 | - `TopAppBar` |
| 43 | - `SmallTopAppBar` |
| 44 | - `CenterAlignedTopAppBar` |
| 45 | - `MediumTopAppBar` |
| 46 | - `LargeTopAppBar` |
| 47 | - `BottomAppBar` |
| 48 | - `ModalDrawerSheet` |
| 49 | - `DismissibleDrawerSheet` |
| 50 | - `PermanentDrawerSheet` |
| 51 | - `ModalBottomSheet` |
| 52 | - `NavigationBar` |
| 53 | - `NavigationRail` |
| 54 | - For Material 2 Components, use the `windowInsets`parameter to apply insets manually for `BottomAppBar`, `TopAppBar` and `BottomNavigation`. **DO NOT** apply padding to the parent container; instead, pass insets directly to the App Bar component. Applying padding to the parent container prevents the App Bar background from drawing into the system bar area. For example, for `TopAppBar`, choose only one of the following options: |
| 55 | 1. **PREFERRED:** `TopAppBar(windowInsets = AppBarDefaults.topAppBarWindowInsets)` |
| 56 | 2. `TopAppBar(windowInsets = WindowInsets.systemBars.exclude(WindowInsets.navigationBars))` |
| 57 | 3. `TopAppBar(windowInsets = WindowInsets.systemBars.add(WindowInsets.captionBar))` |
| 58 | 2. For components outside a Scaffold, use padding modifiers, such as `Modifier.safeDrawingPadding()` or `Modifier.windowInsetsPadding(WindowInsets.safeDrawing)`. |
| 59 | |
| 60 | |
| 61 | ```kotlin |
| 62 | Box( |
| 63 | modifier = Modifier |
| 64 | .fillMaxSize() |
| 65 | .safeDrawingPadding() |
| 66 | ) { |
| 67 | Button( |
| 68 | onClick = {}, |
| 69 | modifier = Modifier.align(Alignment.BottomCenter) |
| 70 | ) { |
| 71 | Text("Login") |
| 72 | } |
| 73 | } |
| 74 | ``` |
| 75 | |
| 76 | <br /> |
| 77 | |
| 78 | 3. For deeply nested components with excessive padding, use `WindowInsetsRulers` (e.g. `Modifier.fitInside(WindowInsetsRulers.SafeDrawing.current)`). See the *IME* section for a code sample. |
| 79 | |
| 80 | 4. When you need an element (e.g. a custom header or decorative scrim) to |
| 81 | equal the dimensions of a system bar, use inset size modifiers (e.g. |
| 82 | `Modifier.windowInsetsTopHeight(WindowInsets.systemBars)`). |
| 83 | See the *Lists* section for a code sample. |
| 84 | |
| 85 | ## Adaptive Scaffolds |
| 86 | |
| 87 | - `NavigationSuiteScaffold` manages safe areas for its own components, like the `NavigationRail` or `NavigationBar`. However, the adaptive scaffolds (e.g. `NavigationSuiteScaffold`, `ListDetailPaneScaffold`) don't propagate PaddingValues to their inner contents. You **MUST** apply insets to **individual** screens or components (e.g., list `contentPadding` or FAB padding) as described in *Step 3* . **DO NOT** apply `safeDrawingPadding` or similar modifiers to the `NavigationSuiteScaffold` parent. This clips and prevents an edge-to-edge screen. |
| 88 | |
| 89 | ## IME |
| 90 | |
| 91 | - For e |