0
# Split Pane Layouts
1
2
Resizable split panel layouts with horizontal and vertical orientations, customizable splitters, and state management for creating flexible UI layouts with draggable dividers.
3
4
## Capabilities
5
6
### Split Pane Composables
7
8
Main composable functions for creating horizontal and vertical split layouts.
9
10
```kotlin { .api }
11
/**
12
* Creates a horizontal split pane with left and right panels separated by a draggable splitter
13
* @param splitPaneState State object controlling the split position and behavior
14
* @param modifier Modifier to be applied to the split pane
15
* @param content DSL content for defining first, second panels and splitter
16
*/
17
@ExperimentalSplitPaneApi
18
@Composable
19
fun HorizontalSplitPane(
20
splitPaneState: SplitPaneState,
21
modifier: Modifier = Modifier,
22
content: SplitPaneScope.() -> Unit
23
)
24
25
/**
26
* Creates a vertical split pane with top and bottom panels separated by a draggable splitter
27
* @param splitPaneState State object controlling the split position and behavior
28
* @param modifier Modifier to be applied to the split pane
29
* @param content DSL content for defining first, second panels and splitter
30
*/
31
@ExperimentalSplitPaneApi
32
@Composable
33
fun VerticalSplitPane(
34
splitPaneState: SplitPaneState,
35
modifier: Modifier = Modifier,
36
content: SplitPaneScope.() -> Unit
37
)
38
```
39
40
**Usage Examples:**
41
42
```kotlin
43
import org.jetbrains.compose.splitpane.*
44
45
@OptIn(ExperimentalSplitPaneApi::class)
46
@Composable
47
fun FileBrowser() {
48
val splitState = rememberSplitPaneState(initialPositionPercentage = 0.25f)
49
50
HorizontalSplitPane(
51
splitPaneState = splitState,
52
modifier = Modifier.fillMaxSize()
53
) {
54
first(minSize = 150.dp) {
55
// File tree panel
56
FileTreePanel()
57
}
58
59
second(minSize = 300.dp) {
60
// File content panel
61
FileContentPanel()
62
}
63
64
splitter {
65
visiblePart {
66
Box(
67
modifier = Modifier
68
.width(2.dp)
69
.fillMaxHeight()
70
.background(MaterialTheme.colors.onSurface.copy(alpha = 0.12f))
71
)
72
}
73
}
74
}
75
}
76
```
77
78
### State Management
79
80
State management for controlling split pane position and behavior.
81
82
```kotlin { .api }
83
/**
84
* Creates and remembers a SplitPaneState
85
* @param initialPositionPercentage Initial position as percentage (0f to 1f)
86
* @param moveEnabled Whether the splitter can be moved by the user
87
* @return SplitPaneState instance
88
*/
89
@ExperimentalSplitPaneApi
90
@Composable
91
fun rememberSplitPaneState(
92
initialPositionPercentage: Float = 0f,
93
moveEnabled: Boolean = true
94
): SplitPaneState
95
96
/**
97
* State object that controls the position and behavior of a split pane
98
*/
99
@ExperimentalSplitPaneApi
100
class SplitPaneState {
101
/** Current position as percentage (0f = fully collapsed first panel, 1f = fully collapsed second panel) */
102
var positionPercentage: Float
103
104
/** Whether the user can drag the splitter to resize panels */
105
var moveEnabled: Boolean
106
107
/**
108
* Programmatically move the splitter by a relative amount
109
* @param delta Amount to move (-1f to 1f range)
110
*/
111
fun dispatchRawMovement(delta: Float)
112
}
113
```
114
115
### DSL Scopes
116
117
Domain-specific language scopes for defining split pane content and behavior.
118
119
```kotlin { .api }
120
/**
121
* Scope for defining split pane content using DSL
122
*/
123
@ExperimentalSplitPaneApi
124
interface SplitPaneScope {
125
/**
126
* Defines the first panel content (left in horizontal, top in vertical)
127
* @param minSize Minimum size constraint for this panel
128
* @param content Composable content for the panel
129
*/
130
fun first(minSize: Dp = 0.dp, content: @Composable () -> Unit)
131
132
/**
133
* Defines the second panel content (right in horizontal, bottom in vertical)
134
* @param minSize Minimum size constraint for this panel
135
* @param content Composable content for the panel
136
*/
137
fun second(minSize: Dp = 0.dp, content: @Composable () -> Unit)
138
139
/**
140
* Defines the splitter appearance and behavior
141
* @param block Configuration block for splitter styling and handles
142
*/
143
fun splitter(block: SplitterScope.() -> Unit)
144
}
145
146
/**
147
* Scope for configuring splitter appearance and behavior
148
*/
149
@ExperimentalSplitPaneApi
150
interface SplitterScope {
151
/**
152
* Defines the visible part of the splitter (the divider line/area)
153
* @param content Composable content for the visible splitter
154
*/
155
fun visiblePart(content: @Composable () -> Unit)
156
157
/**
158
* Adds a draggable handle to the splitter
159
* @param alignment Position of the handle relative to the splitter
160
* @param content Composable content for the handle with HandleScope
161
*/
162
fun handle(
163
alignment: SplitterHandleAlignment = SplitterHandleAlignment.ABOVE,
164
content: @Composable HandleScope.() -> Unit
165
)
166
}
167
168
/**
169
* Scope for defining draggable handle content
170
*/
171
@ExperimentalSplitPaneApi
172
interface HandleScope {
173
/**
174
* Marks a composable as the draggable handle area
175
* @return Modifier that enables drag functionality
176
*/
177
fun Modifier.markAsHandle(): Modifier
178
}
179
```
180
181
### Splitter Handle Alignment
182
183
Enum defining where handles can be positioned relative to the splitter.
184
185
```kotlin { .api }
186
/**
187
* Alignment options for splitter handles
188
*/
189
@ExperimentalSplitPaneApi
190
enum class SplitterHandleAlignment {
191
/** Handle positioned before the splitter (left of vertical, above horizontal) */
192
BEFORE,
193
194
/** Handle positioned above/on top of the splitter */
195
ABOVE,
196
197
/** Handle positioned after the splitter (right of vertical, below horizontal) */
198
AFTER
199
}
200
```
201
202
**Advanced Usage Example:**
203
204
```kotlin
205
@OptIn(ExperimentalSplitPaneApi::class)
206
@Composable
207
fun CodeEditor() {
208
val horizontalSplit = rememberSplitPaneState(0.7f)
209
val verticalSplit = rememberSplitPaneState(0.8f)
210
211
HorizontalSplitPane(splitPaneState = horizontalSplit) {
212
first(minSize = 200.dp) {
213
VerticalSplitPane(splitPaneState = verticalSplit) {
214
first(minSize = 100.dp) {
215
CodeEditorPanel()
216
}
217
second(minSize = 50.dp) {
218
TerminalPanel()
219
}
220
splitter {
221
visiblePart {
222
Divider(color = MaterialTheme.colors.onSurface.copy(0.12f))
223
}
224
}
225
}
226
}
227
228
second(minSize = 150.dp) {
229
SidebarPanel()
230
}
231
232
splitter {
233
visiblePart {
234
Box(
235
modifier = Modifier
236
.width(4.dp)
237
.fillMaxHeight()
238
.background(Color.Transparent)
239
)
240
}
241
handle(SplitterHandleAlignment.ABOVE) {
242
Icon(
243
Icons.Default.DragHandle,
244
contentDescription = "Resize",
245
modifier = Modifier
246
.markAsHandle()
247
.size(16.dp)
248
.background(
249
MaterialTheme.colors.surface,
250
RoundedCornerShape(2.dp)
251
)
252
.padding(2.dp)
253
)
254
}
255
}
256
}
257
}
258
```
259
260
### Experimental API Note
261
262
All SplitPane APIs are marked with `@ExperimentalSplitPaneApi` and require opt-in:
263
264
```kotlin
265
@file:OptIn(ExperimentalSplitPaneApi::class)
266
```
267
268
or at usage sites:
269
270
```kotlin
271
@OptIn(ExperimentalSplitPaneApi::class)
272
@Composable
273
fun MyComposable() {
274
// SplitPane usage
275
}
276
```