# Dock > Dynamic dock window management and layout system with resizable, draggable, and floatable panels. --- .. toc:: .. llms_copy::Dock `dash-dock` is a Dash component library that provides a powerful window management and layout system for your Dash applications. Based on FlexLayout, it features dockable, resizable, and floatable windows with drag-and-drop tab management, maximize, minimize, and pop-out window controls, flexible row and column layouts with nested containers, custom headers and styling for individual tabs, persistent layout state management, and compatibility with both Dash 2 and Dash 3. Available in free (3 tabs) and premium (unlimited tabs) versions. ### Installation [Visit GitHub Repo](https://github.com/pip-install-python/dash-dock) ⭐️ Star this component on GitHub! Stay up to date on new releases and browse the codebase. ```bash pip install dash-dock ``` --- ### Quick Start Create a basic dockable layout with two tabs. Drag tabs to rearrange, resize panels, or float them as separate windows. .. exec::docs.dash_dock.simple_usage :code: false ```python # File: docs/dash_dock/simple_usage.py import dash from dash import html, Input, Output, State, callback, _dash_renderer, dcc import dash_dock from dash_iconify import DashIconify import dash_mantine_components as dmc import os from dotenv import load_dotenv from pathlib import Path dock_config = { "global": { "tabEnableClose": False, "tabEnableFloat": True }, "layout": { "type": "row", "children": [ { "type": "tabset", "children": [ { "type": "tab", "name": "Tab 1", "component": "text", "id": "tab-1", } ] }, { "type": "tabset", "children": [ { "type": "tab", "name": "Tab 2", "component": "text", "id": "tab-2", } ] } ] } } # Create tab content components tab_components = [ dash_dock.Tab( id="tab-1", children=[ html.H3("Tab 1 Content"), ] ), dash_dock.Tab( id="tab-2", children=[ html.H3("Tab 2 Content"), ] ) ] # Main app layout component = html.Div([ html.H1("Dash Dock Example"), dmc.Box( dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, useStateForModel=True, style={ 'position': 'relative', 'height': '100%', 'width': '100%', 'overflow': 'hidden' } ), style={ 'height': '40vh', 'width': '100%', 'position': 'relative', 'overflow': 'hidden' } ) ]) ``` --- ### Layout Configuration The dock layout is defined using a FlexLayout model configuration object. This determines the initial structure of your dock layout. **Basic Layout Structure:** ```python dock_config = { "global": { "tabEnableClose": True, # Allow closing tabs "tabEnableFloat": True, # Allow floating tabs "tabEnableRename": False, # Disable tab renaming }, "layout": { "type": "row", # Top-level container type "children": [ { "type": "tabset", # Container for tabs "children": [ { "type": "tab", "name": "Dashboard", "component": "dashboard", "id": "tab-dashboard", } ] }, { "type": "tabset", "children": [ { "type": "tab", "name": "Analytics", "component": "analytics", "id": "tab-analytics", } ] } ] } } ``` **Layout Types:** - **`row`**: Arranges children horizontally - **`tabset`**: Container for tabs with tab bar - **`tab`**: Individual tab with content - **`col`**: Arranges children vertically (alternative to row) --- ### Tab Components Each tab requires a corresponding `Tab` component that defines the content to display when that tab is active. ```python import dash_dock from dash import html tab_components = [ dash_dock.Tab( id="tab-dashboard", children=[ html.H3("Dashboard"), html.P("Main dashboard content here"), ] ), dash_dock.Tab( id="tab-analytics", children=[ html.H3("Analytics"), html.P("Analytics content here"), ] ) ] ``` **Important:** The `id` in the Tab component must match the `id` in the layout configuration. --- ### Complete Example Combine the layout configuration and tab components in a full application. ```python from dash import Dash, html import dash_dock import dash_mantine_components as dmc app = Dash(__name__) # Define layout structure dock_config = { "global": { "tabEnableClose": False, "tabEnableFloat": True }, "layout": { "type": "row", "children": [ { "type": "tabset", "weight": 60, # Takes 60% of width "children": [ { "type": "tab", "name": "Main View", "component": "main", "id": "tab-main", } ] }, { "type": "tabset", "weight": 40, # Takes 40% of width "children": [ { "type": "tab", "name": "Sidebar", "component": "sidebar", "id": "tab-sidebar", } ] } ] } } # Create tab content tab_components = [ dash_dock.Tab( id="tab-main", children=[html.H3("Main Content")] ), dash_dock.Tab( id="tab-sidebar", children=[html.H3("Sidebar Content")] ) ] # App layout app.layout = dmc.Box( dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, useStateForModel=True, style={ 'position': 'relative', 'height': '100%', 'width': '100%', 'overflow': 'hidden' } ), style={ 'height': '100vh', 'width': '100%', 'position': 'relative', 'overflow': 'hidden' } ) if __name__ == '__main__': app.run(debug=True) ``` --- ### Global Configuration Options Control default behaviors for all tabs using the `global` object in your model configuration. ```python "global": { "tabEnableClose": True, # Show close button on tabs "tabEnableFloat": True, # Allow tabs to float as windows "tabEnableRename": False, # Disable tab renaming "tabEnableDrag": True, # Allow dragging tabs to reorder "tabSetEnableMaximize": True, # Show maximize button on tabsets "tabSetEnableDrop": True, # Allow dropping tabs into tabsets "borderBarSize": 30, # Size of splitter bars in pixels "tabSetMinWidth": 100, # Minimum width of tabsets "tabSetMinHeight": 100, # Minimum height of tabsets } ``` --- ### Nested Layouts Create complex layouts by nesting rows and columns within each other. ```python dock_config = { "global": { "tabEnableClose": False, "tabEnableFloat": True }, "layout": { "type": "row", "children": [ # Left column with stacked tabs { "type": "col", "weight": 30, "children": [ { "type": "tabset", "weight": 50, "children": [ { "type": "tab", "name": "Files", "id": "tab-files" } ] }, { "type": "tabset", "weight": 50, "children": [ { "type": "tab", "name": "Outline", "id": "tab-outline" } ] } ] }, # Right side with main content { "type": "tabset", "weight": 70, "children": [ { "type": "tab", "name": "Editor", "id": "tab-editor" } ] } ] } } ``` **Weight System:** The `weight` property determines the relative size of containers. In the example above, the left column takes 30% (30/(30+70)) and the right takes 70% of the width. --- ### Premium Version with API Key The premium version removes the 3-tab limitation and provides unlimited tabs for complex applications. .. exec::docs.dash_dock.api_example :code: false ```python # File: docs/dash_dock/api_example.py import dash from dash import Input, Output, html, dcc, clientside_callback, callback import dash_dock from dash_iconify import DashIconify import dash_mantine_components as dmc import os from dotenv import load_dotenv from pathlib import Path # Setup the .env file to protect your API Key env_path = Path('.') / '.env' load_dotenv(env_path) API_KEY = os.getenv("API_KEY") styles = { "container": { "width": "100%", "height": "100vh", "display": "flex", "flexDirection": "column", "alignItems": "center", "justifyContent": "center", "padding": "20px", }, "header": { "textAlign": "center", "marginBottom": "20px", "width": "100%", "maxWidth": "600px", }, "apiInput": { "width": "100%", "maxWidth": "400px", "padding": "8px", "marginBottom": "10px", "border": "1px solid #ccc", "borderRadius": "4px", }, "description": { "fontSize": "14px", "color": "#666", "marginBottom": "20px", "textAlign": "center", }, "demoArea": { "display": "flex", "width": "100%", "height": "500px", # Fixed height for demo area "backgroundColor": "white", "justifyContent": "center", "alignItems": "center", "position": "relative", }, "planet": { "height": "120px", "width": "120px", "borderRadius": "50%", "backgroundColor": "#1976d2", "display": "flex", "justifyContent": "center", "alignItems": "center", "color": "white", "cursor": "pointer", "transition": "all 0.3s", "position": "relative", }, "satellite": { "height": "40px", "width": "40px", # 'borderRadius': '50%', # 'backgroundColor': '#ff4081', "display": "flex", "justifyContent": "center", "alignItems": "center", "color": "white", "cursor": "pointer", "zIndex": 1, }, "gridColumn": { "height": "300px", "width": "100%", "display": "flex", "justifyContent": "center", "alignItems": "center", "position": "relative", "padding": "20px", "boxSizing": "border-box", }, "features": { "marginTop": "20px", "padding": "20px", "backgroundColor": "#f5f5f5", "borderRadius": "8px", # "maxWidth": "600px", "width": "100%", 'color': 'black' }, "featureList": {"listStyle": "none", "padding": "0", "margin": "0"}, "featureItem": { "padding": "8px 0", "display": "flex", "alignItems": "center", "gap": "8px", }, } # Define the dock layout configuration dock_config = { "global": { "tabEnableClose": False, "tabEnableFloat": True, }, "borders": [ { "type": "border", "location": "bottom", "size": 100, "children": [ { "type": "tab", "name": "Console", "component": "text", "id": "console-tab" } ] }, { "type": "border", "location": "left", "size": 250, "children": [ { "type": "tab", "name": "Explorer", "component": "text", "id": "explorer-tab" } ] } ], "layout": { "type": "row", "weight": 100, "children": [ { "type": "tabset", "weight": 60, "selected": 0, "children": [ { "type": "tab", "name": "Main View", "component": "text", "enableFloat": True, "id": "main-view-tab", } ] }, { "type": "tabset", "weight": 40, "selected": 0, "children": [ { "type": "tab", "name": "Data Properties", "component": "text", "id": "data-properties-tab", }, { "type": "tab", "name": "Chart Properties", "component": "text", "id": "chart-properties-tab", } ] } ] } } # Sample data for charts chart_data = [ {"month": "January", "value": 10, "x": 1, "y": 10}, {"month": "February", "value": 11, "x": 2, "y": 11}, {"month": "March", "value": 9, "x": 3, "y": 9}, {"month": "April", "value": 16, "x": 4, "y": 16}, {"month": "May", "value": 14, "x": 5, "y": 14} ] # Scatter chart data format is different, so we need to transform it scatter_data = [ { "color": "blue.6", "name": "Sample Data", "data": [{"x": d["x"], "y": d["y"]} for d in chart_data] } ] # Create theme switch component theme_switch = dmc.Switch( offLabel=DashIconify(icon="radix-icons:sun", width=15, style={"color": "#FFB300"}), onLabel=DashIconify(icon="radix-icons:moon", width=15, style={"color": "#FFD700"}), id="color-scheme-switch", size="md", persistence=True, color="gray" ) # Create the tab content components tab_components = [ dash_dock.Tab( id="explorer-tab", children=[ html.H4("Explorer"), dcc.Checklist( id="dataset-selector", options=[ {"label": "Dataset A", "value": "a"}, {"label": "Dataset B", "value": "b"}, {"label": "Dataset C", "value": "c"}, ], value=["a"] ) ] ), dash_dock.Tab( id="main-view-tab", children=[ html.H3("Main Visualization"), dmc.Box(id="selected-datasets-display"), dmc.Box(id="main-chart-container"), # Container for dynamic chart ] ), dash_dock.Tab( id="data-properties-tab", children=[ html.H4("Data Properties"), html.Button("Refresh Data", id="refresh-data-btn"), dmc.Box(id="data-refresh-status") ] ), dash_dock.Tab( id="chart-properties-tab", children=[ html.H4("Chart Properties"), dmc.RadioGroup( id="chart-type-selector", label="Select Chart Type", value="line", children=dmc.Stack([ dmc.Radio(label="Line Chart", value="line"), dmc.Radio(label="Bar Chart", value="bar"), dmc.Radio(label="Scatter Chart", value="scatter"), ]) ), dmc.Box(id="selected-chart-type") ] ), dash_dock.Tab( id="console-tab", children=[ html.H4("Console"), html.Pre(id="console-output", style={"height": "80px", "overflow": "auto"}) ] ), ] # Custom headers for tabs custom_headers = { "main-view-tab": html.Div([ DashIconify(icon="fluent-emoji:bar-chart", width=15), "Main View" ], style={"display": "flex", "alignItems": "center"}), "explorer-tab": html.Div([ DashIconify(icon="flat-color-icons:folder", width=15), "Explorer" ], style={"display": "flex", "alignItems": "center"}) } component = dmc.Box( html.Div( id="app-container", children=[ # Header section - fixed at top html.Div( id="app-header", children=[ html.Link( rel="stylesheet", href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" ), dmc.Paper( children=[ dmc.Group([ dmc.Title("Dash Dock Example", order=3), theme_switch ], justify="apart", align="center") ], p="md", shadow="xs", radius="md", withBorder=True, style={"height": "100%"} ), ] ), # DashDock container - fills remaining space html.Div(id="dash-dock-container", children=dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, useStateForModel=True, headers=custom_headers, apiKey=API_KEY, debugMode=True, supportsPopout=False, style={ 'position': 'relative', # Changed from absolute 'height': '100%', # Take full height of parent 'width': '100%', # Take full width of parent 'overflow': 'hidden' # Removed !important and semicolons } ), style={ 'height': '60vh', # Fixed height on the container 'width': '100%', # Full width 'position': 'relative', # Create positioning context 'overflow': 'hidden' # Prevent content overflow }) ] ) ) # Callback for dataset selection @callback( Output('selected-datasets-display', 'children'), [Input('dataset-selector', 'value')] ) def update_selected_datasets(selected_datasets): if not selected_datasets: return "No datasets selected" return f"Selected datasets: {', '.join(selected_datasets)}" # Callback for chart type selection @callback( Output('selected-chart-type', 'children'), [Input('chart-type-selector', 'value')] ) def update_chart_type(chart_type): return f"Selected chart type: {chart_type}" # Callback for data refresh @callback( Output('data-refresh-status', 'children'), Output('console-output', 'children'), [Input('refresh-data-btn', 'n_clicks')] ) def refresh_data(n_clicks): if not n_clicks: return "Data not refreshed yet", "Console initialized. Waiting for events..." console_msg = f"Data refresh requested at click {n_clicks}" return f"Data refreshed {n_clicks} times", console_msg # Callback to update the chart based on the selected chart type @callback( Output('main-chart-container', 'children'), [Input('chart-type-selector', 'value')] ) def update_chart(chart_type): if chart_type == "line": return dmc.LineChart( h=400, dataKey="month", data=chart_data, withLegend=True, xAxisLabel="Month", yAxisLabel="Value", series=[ {"name": "value", "color": "blue.6", "label": "Sample Data"} ] ) elif chart_type == "bar": return dmc.BarChart( h=400, dataKey="month", data=chart_data, withLegend=True, xAxisLabel="Month", yAxisLabel="Value", series=[ {"name": "value", "color": "blue.6", "label": "Sample Data"} ] ) elif chart_type == "scatter": return dmc.ScatterChart( h=400, data=scatter_data, dataKey={"x": "x", "y": "y"}, xAxisLabel="X Value", yAxisLabel="Y Value", withLegend=True ) else: return html.Div("Invalid chart type selected") ``` **Obtaining an API Key:** Visit [Plotly Pro Shop](https://plotly.pro/product/prod_SY2s0MuBRidQ1q) to purchase an API key for the premium version. API keys are delivered to the purchase email within 24 hours. **Using the API Key:** ```python import os from dotenv import load_dotenv load_dotenv() API_KEY = os.getenv("API_KEY") dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, apiKey=API_KEY, # Enable premium features ) ``` **Premium Features:** - **Unlimited Tabs**: No restriction on the number of tabs - **Advanced Layouts**: Create complex multi-panel applications - **Full Feature Access**: All dock management capabilities enabled --- ### Styling and Customization Customize the appearance of tabs using the `font` property and individual tab styles. ```python dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, font={ 'size': '14px', 'family': 'Inter, sans-serif', 'weight': '500' }, style={ 'position': 'relative', 'height': '100%', 'width': '100%', 'overflow': 'hidden', 'backgroundColor': '#f5f5f5' } ) ``` **Tab-Specific Styling:** Add custom classes or styles through the tab configuration for individual tab appearance customization. --- ### State Management Control whether the dock layout manages its own state internally or uses external state. ```python dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, useStateForModel=True, # Internal state management ) ``` **State Options:** - **`useStateForModel=True`**: Component manages layout state internally (recommended for most cases) - **`useStateForModel=False`**: Layout state controlled externally via callbacks (advanced use cases) --- ### Pop-out Windows Enable tabs to open in separate browser windows for multi-monitor setups. ```python dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, supportsPopout=True, popoutURL='/popout', # URL path for popout windows ) ``` **Note:** Pop-out windows open the content in a new browser window that can be moved to a different monitor. --- ### Realtime Resize Enable real-time content resizing as panels are dragged (may impact performance with complex content). ```python dash_dock.DashDock( id='dock-layout', model=dock_config, children=tab_components, realtimeResize=True, # Update content size during drag ) ``` **Performance Consideration:** Set to `False` (default) for better performance. Content will resize after drag completes. --- ### Component Properties #### DashDock Component | Property | Type | Default | Description | | :------------------ | :-------- | :----------- |:----------------------------------------------------------------------------------------------------------------| | **`id`** | `string` | **Required** | Unique identifier for the component used in Dash callbacks. | | **`model`** | `dict` | **Required** | FlexLayout model configuration defining the layout structure, global settings, and tab configurations. | | **`children`** | `list` | **Required** | Array of Tab components to render in the dock layout. Each Tab's id must match a tab id in the model. | | `headers` | `dict` | `None` | Custom header components for tabs. Keys are tab IDs, values are React components. | | `useStateForModel` | `bool` | `False` | If true, component manages layout state internally. If false, state is controlled externally. | | `font` | `dict` | `None` | Font styling object for tabs with size, family, and weight properties. | | `supportsPopout` | `bool` | `False` | If true, enables pop-out window functionality for tabs. | | `popoutURL` | `string` | `None` | URL path for pop-out windows. Required if supportsPopout is true. | | `realtimeResize` | `bool` | `False` | If true, updates content size in real-time during drag operations. May impact performance. | | `apiKey` | `string` | `None` | API key for premium features. Enables unlimited tabs (free version limited to 3). | | `freeTabLimit` | `number` | `3` | Maximum number of tabs allowed in free version. Only applies when apiKey is not provided. | | `debugMode` | `bool` | `False` | If true, enables debug logging to console for troubleshooting. | | `style` | `dict` | `{}` | CSS styles object for the dock container. Recommended to set position, height, width, and overflow. | | `setProps` | `func` | (Dash Internal) | Callback function to update component properties. | | `loading_state` | `object` | (Dash Internal) | Object describing the loading state of the component or its props. | #### Tab Component | Property | Type | Default | Description | | :--------------- | :------- | :----------- |:----------------------------------------------------------------------------------------------------------------| | **`id`** | `string` | **Required** | Unique identifier that must match the tab id in the DashDock model configuration. | | `children` | `list` | `[]` | React components to render inside this tab when it is active. | | `setProps` | `func` | (Dash Internal) | Callback function to update component properties. | | `loading_state` | `object` | (Dash Internal) | Object describing the loading state of the component or its props. | --- ### FlexLayout Model Reference The `model` property accepts a FlexLayout configuration object with the following structure: **Global Configuration:** ```python "global": { "tabEnableClose": bool, # Allow closing tabs "tabEnableFloat": bool, # Allow floating tabs as windows "tabEnableRename": bool, # Allow renaming tabs "tabEnableDrag": bool, # Allow dragging tabs to reorder "tabSetEnableMaximize": bool, # Show maximize button "tabSetEnableDrop": bool, # Allow dropping tabs "borderBarSize": number, # Splitter bar size in pixels "tabSetMinWidth": number, # Minimum tabset width "tabSetMinHeight": number, # Minimum tabset height } ``` **Layout Structure:** ```python "layout": { "type": "row" | "col", # Container orientation "weight": number, # Relative size (optional) "children": [ # Child elements { "type": "tabset", # Tab container "weight": number, # Relative size "children": [ { "type": "tab", # Individual tab "name": string, # Display name "id": string, # Unique identifier "component": string # Component reference } ] } ] } ``` --- ### Free vs Premium Comparison | Feature | Free Version | Premium Version | |:---------------------------|:-------------|:----------------| | Maximum Tabs | 3 | Unlimited | | Dockable Windows | ✅ | ✅ | | Resizable Panels | ✅ | ✅ | | Drag & Drop Tabs | ✅ | ✅ | | Float Windows | ✅ | ✅ | | Pop-out Windows | ✅ | ✅ | | Nested Layouts | ✅ | ✅ | | Custom Styling | ✅ | ✅ | | API Key Required | ❌ | ✅ | | Commercial Use | ✅ | ✅ | --- ### Contributing Contributions to dash-dock are welcome! Please refer to the project's issues on GitHub for any feature requests or bug reports. ### License This project is created under [Pip Install Python LLC](https://pip-install-python.com) and licensed under the MIT License. --- *Source: /pip/dash_dock* *Generated with dash-improve-my-llms*