CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-components--components

Additional UI components for Compose Multiplatform including SplitPane layouts, resource loading, animated images, and UI tooling preview support

Pending
Overview
Eval results
Files

splitpane.mddocs/

Split Pane Layouts

Resizable split panel layouts with horizontal and vertical orientations, customizable splitters, and state management for creating flexible UI layouts with draggable dividers.

Capabilities

Split Pane Composables

Main composable functions for creating horizontal and vertical split layouts.

/**
 * Creates a horizontal split pane with left and right panels separated by a draggable splitter
 * @param splitPaneState State object controlling the split position and behavior
 * @param modifier Modifier to be applied to the split pane
 * @param content DSL content for defining first, second panels and splitter
 */
@ExperimentalSplitPaneApi
@Composable
fun HorizontalSplitPane(
    splitPaneState: SplitPaneState,
    modifier: Modifier = Modifier,
    content: SplitPaneScope.() -> Unit
)

/**
 * Creates a vertical split pane with top and bottom panels separated by a draggable splitter
 * @param splitPaneState State object controlling the split position and behavior
 * @param modifier Modifier to be applied to the split pane  
 * @param content DSL content for defining first, second panels and splitter
 */
@ExperimentalSplitPaneApi
@Composable
fun VerticalSplitPane(
    splitPaneState: SplitPaneState,
    modifier: Modifier = Modifier,
    content: SplitPaneScope.() -> Unit
)

Usage Examples:

import org.jetbrains.compose.splitpane.*

@OptIn(ExperimentalSplitPaneApi::class)
@Composable
fun FileBrowser() {
    val splitState = rememberSplitPaneState(initialPositionPercentage = 0.25f)
    
    HorizontalSplitPane(
        splitPaneState = splitState,
        modifier = Modifier.fillMaxSize()
    ) {
        first(minSize = 150.dp) {
            // File tree panel
            FileTreePanel()
        }
        
        second(minSize = 300.dp) {
            // File content panel
            FileContentPanel()
        }
        
        splitter {
            visiblePart {
                Box(
                    modifier = Modifier
                        .width(2.dp)
                        .fillMaxHeight()
                        .background(MaterialTheme.colors.onSurface.copy(alpha = 0.12f))
                )
            }
        }
    }
}

State Management

State management for controlling split pane position and behavior.

/**
 * Creates and remembers a SplitPaneState
 * @param initialPositionPercentage Initial position as percentage (0f to 1f)
 * @param moveEnabled Whether the splitter can be moved by the user
 * @return SplitPaneState instance
 */
@ExperimentalSplitPaneApi
@Composable
fun rememberSplitPaneState(
    initialPositionPercentage: Float = 0f,
    moveEnabled: Boolean = true
): SplitPaneState

/**
 * State object that controls the position and behavior of a split pane
 */
@ExperimentalSplitPaneApi
class SplitPaneState {
    /** Current position as percentage (0f = fully collapsed first panel, 1f = fully collapsed second panel) */
    var positionPercentage: Float
    
    /** Whether the user can drag the splitter to resize panels */
    var moveEnabled: Boolean
    
    /** 
     * Programmatically move the splitter by a relative amount
     * @param delta Amount to move (-1f to 1f range)
     */
    fun dispatchRawMovement(delta: Float)
}

DSL Scopes

Domain-specific language scopes for defining split pane content and behavior.

/**
 * Scope for defining split pane content using DSL
 */
@ExperimentalSplitPaneApi
interface SplitPaneScope {
    /**
     * Defines the first panel content (left in horizontal, top in vertical)
     * @param minSize Minimum size constraint for this panel
     * @param content Composable content for the panel
     */
    fun first(minSize: Dp = 0.dp, content: @Composable () -> Unit)
    
    /**
     * Defines the second panel content (right in horizontal, bottom in vertical)
     * @param minSize Minimum size constraint for this panel
     * @param content Composable content for the panel
     */
    fun second(minSize: Dp = 0.dp, content: @Composable () -> Unit)
    
    /**
     * Defines the splitter appearance and behavior
     * @param block Configuration block for splitter styling and handles
     */
    fun splitter(block: SplitterScope.() -> Unit)
}

/**
 * Scope for configuring splitter appearance and behavior
 */
@ExperimentalSplitPaneApi
interface SplitterScope {
    /**
     * Defines the visible part of the splitter (the divider line/area)
     * @param content Composable content for the visible splitter
     */
    fun visiblePart(content: @Composable () -> Unit)
    
    /**
     * Adds a draggable handle to the splitter
     * @param alignment Position of the handle relative to the splitter
     * @param content Composable content for the handle with HandleScope
     */
    fun handle(
        alignment: SplitterHandleAlignment = SplitterHandleAlignment.ABOVE,
        content: @Composable HandleScope.() -> Unit
    )
}

/**
 * Scope for defining draggable handle content
 */
@ExperimentalSplitPaneApi
interface HandleScope {
    /**
     * Marks a composable as the draggable handle area
     * @return Modifier that enables drag functionality
     */
    fun Modifier.markAsHandle(): Modifier
}

Splitter Handle Alignment

Enum defining where handles can be positioned relative to the splitter.

/**
 * Alignment options for splitter handles
 */
@ExperimentalSplitPaneApi
enum class SplitterHandleAlignment {
    /** Handle positioned before the splitter (left of vertical, above horizontal) */
    BEFORE,
    
    /** Handle positioned above/on top of the splitter */
    ABOVE, 
    
    /** Handle positioned after the splitter (right of vertical, below horizontal) */
    AFTER
}

Advanced Usage Example:

@OptIn(ExperimentalSplitPaneApi::class)
@Composable
fun CodeEditor() {
    val horizontalSplit = rememberSplitPaneState(0.7f)
    val verticalSplit = rememberSplitPaneState(0.8f)
    
    HorizontalSplitPane(splitPaneState = horizontalSplit) {
        first(minSize = 200.dp) {
            VerticalSplitPane(splitPaneState = verticalSplit) {
                first(minSize = 100.dp) {
                    CodeEditorPanel()
                }
                second(minSize = 50.dp) {
                    TerminalPanel()
                }
                splitter {
                    visiblePart {
                        Divider(color = MaterialTheme.colors.onSurface.copy(0.12f))
                    }
                }
            }
        }
        
        second(minSize = 150.dp) {
            SidebarPanel()
        }
        
        splitter {
            visiblePart {
                Box(
                    modifier = Modifier
                        .width(4.dp)
                        .fillMaxHeight()
                        .background(Color.Transparent)
                )
            }
            handle(SplitterHandleAlignment.ABOVE) {
                Icon(
                    Icons.Default.DragHandle,
                    contentDescription = "Resize",
                    modifier = Modifier
                        .markAsHandle()
                        .size(16.dp)
                        .background(
                            MaterialTheme.colors.surface,
                            RoundedCornerShape(2.dp)
                        )
                        .padding(2.dp)
                )
            }
        }
    }
}

Experimental API Note

All SplitPane APIs are marked with @ExperimentalSplitPaneApi and require opt-in:

@file:OptIn(ExperimentalSplitPaneApi::class)

or at usage sites:

@OptIn(ExperimentalSplitPaneApi::class)
@Composable
fun MyComposable() {
    // SplitPane usage
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-components--components

docs

animatedimage.md

index.md

preview.md

resources.md

splitpane.md

tile.json