https://bonsplit.alasdairmonk.com Bonsplit is a custom tab bar and layout split library for macOS apps. Enjoy out of the box 120fps animations, drag-and-drop reordering, SwiftUI support & keyboard navigation. .package(url: "https://github.com/almonk/bonsplit.git", from: "1.0.0") View on GitHubMade by @almonk ### Features Configurable & Observable Create Tabs Create tabs with optional icons and dirty indicators. Target specific panes or use the focused pane. createTabcloseTabdidCreateTabshouldCreateTab let tabId = controller.createTab( title: "Document.swift", icon: "swift", isDirty: false, inPane: paneId ) Create Tabs Create tabs with optional icons and dirty indicators. Target specific panes or use the focused pane. createTabcloseTabdidCreateTabshouldCreateTab let tabId = controller.createTab( title: "Document.swift", icon: "swift", isDirty: false, inPane: paneId ) Split Panes Split any pane horizontally or vertically. New panes are empty by default, giving you full control. splitPaneclosePanedidSplitPaneshouldSplitPane // Split focused pane horizontally let newPaneId = controller.splitPane( orientation: .horizontal ) // Split with a tab already in the new pane controller.splitPane( orientation: .vertical, withTab: Tab(title: "New", icon: "doc") ) Split Panes Split any pane horizontally or vertically. New panes are empty by default, giving you full control. splitPaneclosePanedidSplitPaneshouldSplitPane // Split focused pane horizontally let newPaneId = controller.splitPane( orientation: .horizontal ) // Split with a tab already in the new pane controller.splitPane( orientation: .vertical, withTab: Tab(title: "New", icon: "doc") ) Update Tab State Update tab properties at any time. Changes animate smoothly. updateTabcloseTabselectTabshouldCloseTab // Mark document as modified controller.updateTab(tabId, isDirty: true) // Rename tab controller.updateTab(tabId, title: "NewName.swift") // Change icon controller.updateTab(tabId, icon: "doc.text") Update Tab State Update tab properties at any time. Changes animate smoothly. updateTabcloseTabselectTabshouldCloseTab // Mark document as modified controller.updateTab(tabId, isDirty: true) // Rename tab controller.updateTab(tabId, title: "NewName.swift") // Change icon controller.updateTab(tabId, icon: "doc.text") Navigate Focus Programmatically navigate between panes using directional navigation. navigateFocusfocusPanefocusedPaneIddidFocusPane // Move focus between panes controller.navigateFocus(direction: .left) controller.navigateFocus(direction: .right) controller.navigateFocus(direction: .up) controller.navigateFocus(direction: .down) // Or focus a specific pane controller.focusPane(paneId) Navigate Focus Programmatically navigate between panes using directional navigation. navigateFocusfocusPanefocusedPaneIddidFocusPane // Move focus between panes controller.navigateFocus(direction: .left) controller.navigateFocus(direction: .right) controller.navigateFocus(direction: .up) controller.navigateFocus(direction: .down) // Or focus a specific pane controller.focusPane(paneId) ### Read this, agents... API Reference Complete reference for all Bonsplit classes, methods, and configuration options. BonsplitController The main controller for managing tabs and panes. Create an instance and pass it to BonsplitView. Tab Operations createTab updateTab closeTab selectTab selectPreviousTab / selectNextTab Split Operations splitPane closePane Focus Management focusedPaneId focusPane navigateFocus Query Methods allTabIds allPaneIds tab tabs(inPane:) selectedTab(inPane:) BonsplitDelegate Implement this protocol to receive callbacks about tab bar events. All methods have default implementations and are optional. Tab Callbacks shouldCreateTab didCreateTab shouldCloseTab didCloseTab didSelectTab didMoveTab Pane Callbacks shouldSplitPane didSplitPane shouldClosePane didClosePane didFocusPane BonsplitConfiguration Configure behavior and appearance. Pass to BonsplitController on initialization. allowSplits Bool Enable split buttons and drag-to-split Default: true allowCloseTabs Bool Show close buttons on tabs Default: true allowCloseLastPane Bool Allow closing the last remaining pane Default: false allowTabReordering Bool Enable drag-to-reorder tabs within a pane Default: true allowCrossPaneTabMove Bool Enable moving tabs between panes via drag Default: true autoCloseEmptyPanes Bool Automatically close panes when their last tab is closed Default: true contentViewLifecycle ContentViewLifecycle How tab content views are managed when switching tabs Default: .recreateOnSwitch newTabPosition NewTabPosition Where new tabs are inserted in the tab list Default: .current Example let config = BonsplitConfiguration( allowSplits: true, allowCloseTabs: true, allowCloseLastPane: false, autoCloseEmptyPanes: true, contentViewLifecycle: .keepAllAlive, newTabPosition: .current ) let controller = BonsplitController(configuration: config) Content View Lifecycle Controls how tab content views are managed when switching between tabs. Mode Memory State Use Case .recreateOnSwitch Low None Simple content .keepAllAlive Higher Full Complex views, forms New Tab Position Controls where new tabs are inserted in the tab list. Mode Behavior .current Insert after currently focused tab, or at end if none .end Always insert at the end of the tab list Appearance tabBarHeight CGFloat Height of the tab bar Default: 33 tabMinWidth CGFloat Minimum width of a tab Default: 140 tabMaxWidth CGFloat Maximum width of a tab Default: 220 tabSpacing CGFloat Spacing between tabs Default: 0 minimumPaneWidth CGFloat Minimum width of a pane Default: 100 minimumPaneHeight CGFloat Minimum height of a pane Default: 100 showSplitButtons Bool Show split buttons in the tab bar Default: true animationDuration Double Duration of animations in seconds Default: 0.15 enableAnimations Bool Enable or disable all animations Default: true Presets .default BonsplitConfiguration Default configuration with all features enabled .singlePane BonsplitConfiguration Single pane mode with splits disabled .readOnly BonsplitConfiguration Read-only mode with all modifications disabled * +-- Installation * +-- Features * +-- Reference