|
| 1 | +# SuperBottomSheet |
| 2 | + |
| 3 | +`SuperBottomSheet` is a bottom sheet component in Miuix that slides up from the bottom of the screen. The height automatically adapts to the content size, but will not cover the status bar area. Supports swipe-to-dismiss gestures and custom styling. |
| 4 | + |
| 5 | +<div style="position: relative; max-width: 700px; height: 210px; border-radius: 10px; overflow: hidden; border: 1px solid #777;"> |
| 6 | + <iframe id="demoIframe" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none;" src="../compose/index.html?id=superBottomSheet" title="Demo" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin"></iframe> |
| 7 | +</div> |
| 8 | + |
| 9 | +::: warning |
| 10 | +`SuperBottomSheet` must be used within a `Scaffold` component! |
| 11 | +::: |
| 12 | + |
| 13 | +## Import |
| 14 | + |
| 15 | +```kotlin |
| 16 | +import top.yukonga.miuix.kmp.extra.SuperBottomSheet |
| 17 | +``` |
| 18 | + |
| 19 | +## Basic Usage |
| 20 | + |
| 21 | +SuperBottomSheet component provides basic bottom sheet functionality: |
| 22 | + |
| 23 | +```kotlin |
| 24 | +var showBottomSheet = remember { mutableStateOf(false) } |
| 25 | + |
| 26 | +Scaffold { |
| 27 | + TextButton( |
| 28 | + text = "Show Bottom Sheet", |
| 29 | + onClick = { showBottomSheet.value = true } |
| 30 | + ) |
| 31 | + |
| 32 | + SuperBottomSheet( |
| 33 | + show = showBottomSheet, |
| 34 | + title = "Bottom Sheet Title", |
| 35 | + onDismissRequest = { showBottomSheet.value = false } |
| 36 | + ) { |
| 37 | + Text(text = "This is the content of the bottom sheet") |
| 38 | + } |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +## Properties |
| 43 | + |
| 44 | +### SuperBottomSheet Properties |
| 45 | + |
| 46 | +| Property Name | Type | Description | Default Value | Required | |
| 47 | +| -------------------------- | ---------------------------------- | -------------------------------------------- | ------------------------------------------- | -------- | |
| 48 | +| show | MutableState\<Boolean> | State object to control bottom sheet visibility | - | Yes | |
| 49 | +| modifier | Modifier | Modifier applied to the bottom sheet | Modifier | No | |
| 50 | +| title | String? | Bottom sheet title | null | No | |
| 51 | +| backgroundColor | Color | Bottom sheet background color | SuperBottomSheetDefaults.backgroundColor() | No | |
| 52 | +| enableWindowDim | Boolean | Whether to enable dimming layer | true | No | |
| 53 | +| onDismissRequest | (() -> Unit)? | Callback when bottom sheet is closed | null | No | |
| 54 | +| outsideMargin | DpSize | Bottom sheet external margin | SuperBottomSheetDefaults.outsideMargin | No | |
| 55 | +| insideMargin | DpSize | Bottom sheet internal content margin | SuperBottomSheetDefaults.insideMargin | No | |
| 56 | +| defaultWindowInsetsPadding | Boolean | Whether to apply default window insets padding | true | No | |
| 57 | +| dragHandleColor | Color | Drag indicator color | SuperBottomSheetDefaults.dragHandleColor() | No | |
| 58 | +| content | @Composable ColumnScope.() -> Unit | Bottom sheet content | - | Yes | |
| 59 | + |
| 60 | +### SuperBottomSheetDefaults Object |
| 61 | + |
| 62 | +The SuperBottomSheetDefaults object provides default settings for the SuperBottomSheet component. |
| 63 | + |
| 64 | +#### Properties |
| 65 | + |
| 66 | +| Property Name | Type | Description | |
| 67 | +| ------------- | ------ | -------------------------------------- | |
| 68 | +| outsideMargin | DpSize | Default bottom sheet external margin | |
| 69 | +| insideMargin | DpSize | Default bottom sheet internal margin | |
| 70 | + |
| 71 | +#### Functions |
| 72 | + |
| 73 | +| Function Name | Return Type | Description | |
| 74 | +| ----------------- | ----------- | ------------------------------- | |
| 75 | +| backgroundColor() | Color | Get default background color | |
| 76 | +| dragHandleColor() | Color | Get default drag indicator color | |
| 77 | + |
| 78 | +## Advanced Usage |
| 79 | + |
| 80 | +### Custom Styled Bottom Sheet |
| 81 | + |
| 82 | +```kotlin |
| 83 | +var showBottomSheet = remember { mutableStateOf(false) } |
| 84 | + |
| 85 | +Scaffold { |
| 86 | + TextButton( |
| 87 | + text = "Show Custom Styled Bottom Sheet", |
| 88 | + onClick = { showBottomSheet.value = true } |
| 89 | + ) |
| 90 | + |
| 91 | + SuperBottomSheet( |
| 92 | + show = showBottomSheet, |
| 93 | + title = "Custom Style", |
| 94 | + backgroundColor = MiuixTheme.colorScheme.surfaceVariant, |
| 95 | + dragHandleColor = MiuixTheme.colorScheme.primary, |
| 96 | + outsideMargin = DpSize(16.dp, 0.dp), |
| 97 | + insideMargin = DpSize(32.dp, 16.dp), |
| 98 | + onDismissRequest = { showBottomSheet.value = false } |
| 99 | + ) { |
| 100 | + Column { |
| 101 | + Text("Custom styled bottom sheet") |
| 102 | + Spacer(modifier = Modifier.height(16.dp)) |
| 103 | + TextButton( |
| 104 | + text = "Close", |
| 105 | + onClick = { showBottomSheet.value = false }, |
| 106 | + modifier = Modifier.fillMaxWidth() |
| 107 | + ) |
| 108 | + } |
| 109 | + } |
| 110 | +} |
| 111 | +``` |
| 112 | + |
| 113 | +### Bottom Sheet with List Content |
| 114 | + |
| 115 | +```kotlin |
| 116 | +var showBottomSheet = remember { mutableStateOf(false) } |
| 117 | +var selectedItem by remember { mutableStateOf("") } |
| 118 | + |
| 119 | +Scaffold { |
| 120 | + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { |
| 121 | + TextButton( |
| 122 | + text = "Show Selection List", |
| 123 | + onClick = { showBottomSheet.value = true } |
| 124 | + ) |
| 125 | + |
| 126 | + Text("Selected: $selectedItem") |
| 127 | + } |
| 128 | + |
| 129 | + SuperBottomSheet( |
| 130 | + show = showBottomSheet, |
| 131 | + title = "Select Item", |
| 132 | + onDismissRequest = { showBottomSheet.value = false } |
| 133 | + ) { |
| 134 | + LazyColumn { |
| 135 | + items(20) { index -> |
| 136 | + Text( |
| 137 | + text = "Item ${index + 1}", |
| 138 | + modifier = Modifier |
| 139 | + .fillMaxWidth() |
| 140 | + .clickable { |
| 141 | + selectedItem = "Item ${index + 1}" |
| 142 | + showBottomSheet.value = false |
| 143 | + } |
| 144 | + .padding(vertical = 12.dp) |
| 145 | + ) |
| 146 | + } |
| 147 | + } |
| 148 | + } |
| 149 | +} |
| 150 | +``` |
| 151 | + |
| 152 | +### Without Dimming Layer |
| 153 | + |
| 154 | +```kotlin |
| 155 | +var showBottomSheet = remember { mutableStateOf(false) } |
| 156 | + |
| 157 | +Scaffold { |
| 158 | + TextButton( |
| 159 | + text = "Show Bottom Sheet Without Dim", |
| 160 | + onClick = { showBottomSheet.value = true } |
| 161 | + ) |
| 162 | + |
| 163 | + SuperBottomSheet( |
| 164 | + show = showBottomSheet, |
| 165 | + title = "No Dimming", |
| 166 | + enableWindowDim = false, |
| 167 | + onDismissRequest = { showBottomSheet.value = false } |
| 168 | + ) { |
| 169 | + Text("This bottom sheet has no background dimming layer") |
| 170 | + Spacer(modifier = Modifier.height(16.dp)) |
| 171 | + TextButton( |
| 172 | + text = "Close", |
| 173 | + onClick = { showBottomSheet.value = false }, |
| 174 | + modifier = Modifier.fillMaxWidth() |
| 175 | + ) |
| 176 | + } |
| 177 | +} |
| 178 | +``` |
| 179 | + |
| 180 | +### Bottom Sheet with Form |
| 181 | + |
| 182 | +```kotlin |
| 183 | +var showBottomSheet = remember { mutableStateOf(false) } |
| 184 | +var textFieldValue by remember { mutableStateOf("") } |
| 185 | +var switchState by remember { mutableStateOf(false) } |
| 186 | + |
| 187 | +Scaffold { |
| 188 | + TextButton( |
| 189 | + text = "Show Form Bottom Sheet", |
| 190 | + onClick = { showBottomSheet.value = true } |
| 191 | + ) |
| 192 | + |
| 193 | + SuperBottomSheet( |
| 194 | + show = showBottomSheet, |
| 195 | + title = "Settings Form", |
| 196 | + onDismissRequest = { showBottomSheet.value = false } |
| 197 | + ) { |
| 198 | + Card( |
| 199 | + color = MiuixTheme.colorScheme.secondaryContainer, |
| 200 | + ) { |
| 201 | + TextField( |
| 202 | + modifier = Modifier.padding(vertical = 12.dp), |
| 203 | + value = textFieldValue, |
| 204 | + label = "Enter content", |
| 205 | + maxLines = 1, |
| 206 | + onValueChange = { textFieldValue = it } |
| 207 | + ) |
| 208 | + |
| 209 | + SuperSwitch( |
| 210 | + title = "Switch Option", |
| 211 | + checked = switchState, |
| 212 | + onCheckedChange = { switchState = it } |
| 213 | + ) |
| 214 | + } |
| 215 | + |
| 216 | + Spacer(Modifier.height(12.dp)) |
| 217 | + |
| 218 | + Row( |
| 219 | + horizontalArrangement = Arrangement.SpaceBetween |
| 220 | + ) { |
| 221 | + TextButton( |
| 222 | + text = "Cancel", |
| 223 | + onClick = { showBottomSheet.value = false }, |
| 224 | + modifier = Modifier.weight(1f) |
| 225 | + ) |
| 226 | + Spacer(Modifier.width(20.dp)) |
| 227 | + TextButton( |
| 228 | + text = "Confirm", |
| 229 | + onClick = { showBottomSheet.value = false }, |
| 230 | + modifier = Modifier.weight(1f), |
| 231 | + colors = ButtonDefaults.textButtonColorsPrimary() |
| 232 | + ) |
| 233 | + } |
| 234 | + } |
| 235 | +} |
| 236 | +``` |
| 237 | + |
| 238 | +### Adaptive Content Height |
| 239 | + |
| 240 | +```kotlin |
| 241 | +var showBottomSheet = remember { mutableStateOf(false) } |
| 242 | + |
| 243 | +Scaffold { |
| 244 | + TextButton( |
| 245 | + text = "Show Adaptive Height Bottom Sheet", |
| 246 | + onClick = { showBottomSheet.value = true } |
| 247 | + ) |
| 248 | + |
| 249 | + SuperBottomSheet( |
| 250 | + show = showBottomSheet, |
| 251 | + title = "Adaptive Height", |
| 252 | + onDismissRequest = { showBottomSheet.value = false } |
| 253 | + ) { |
| 254 | + Column(modifier = Modifier.padding(vertical = 16.dp)) { |
| 255 | + Text("The height adapts to content") |
| 256 | + Spacer(modifier = Modifier.height(16.dp)) |
| 257 | + Text("Add as much content as needed") |
| 258 | + Spacer(modifier = Modifier.height(16.dp)) |
| 259 | + Text("But will not cover the status bar area") |
| 260 | + Spacer(modifier = Modifier.height(16.dp)) |
| 261 | + TextButton( |
| 262 | + text = "Close", |
| 263 | + onClick = { showBottomSheet.value = false }, |
| 264 | + modifier = Modifier.fillMaxWidth() |
| 265 | + ) |
| 266 | + } |
| 267 | + } |
| 268 | +} |
| 269 | +``` |
0 commit comments