**Site index:** [https://2plot.dev/llms.txt](https://2plot.dev/llms.txt) — every page on this site, as Markdown.  
**Network index:** [https://2plot.ai/llms.txt](https://2plot.ai/llms.txt) — The 2plot network; start here to discover sibling sites.  
**Sibling sites:** 11 more in The 2plot network — listed in the site index above.  
**Sitemap:** https://2plot.dev/sitemap.xml  



`dash-dock-view` is a professional-grade docking layout system for Dash applications. Build complex, resizable, and rearrangeable panel layouts with ease. It features 4 layout components (DashDockLayout, DashGridLayout, DashSplitLayout, DashPaneLayout), drag & drop tab management, panel positioning (left, right, top, bottom, center), floating panels, layout persistence, and Apple Liquid Glass themes.

### Installation

[Visit GitHub Repo](https://github.com/pip-install-python/dash-dock-view)

```bash
pip install dash-dock-view
```

**Requirements:**
- Python >= 3.7
- Dash >= 2.0

---

### Quick Start

Create a simple docking layout with three panels.



```python
# File: docs/dash_dock_view/docklayout_example.py

"""DashDockLayout example for Dock View documentation."""
from dash import html
import dash_mantine_components as dmc
from dash_iconify import DashIconify
from dash_dock_view import DashDockLayout

# Panel contents
panel_contents = [
    html.Div(
        id="editor-panel",
        children=[
            dmc.Stack([
                dmc.Group([
                    DashIconify(icon="mdi:file-code", width=20),
                    dmc.Text("app.py", fw=500),
                ]),
                dmc.CodeHighlight(
                    language="python",
                    code='from dash import Dash\n\napp = Dash(__name__)\n\nif __name__ == "__main__":\n    app.run(debug=True)',
                ),
            ], p="md")
        ],
        style={"height": "100%"}
    ),
    html.Div(
        id="console-panel",
        children=[
            html.Pre(
                "$ python app.py\n * Running on http://127.0.0.1:8050\n * Debug mode: on\n$ ",
                style={
                    "backgroundColor": "#1e1e1e",
                    "color": "#00ff00",
                    "padding": "10px",
                    "margin": "0",
                    "fontFamily": "monospace",
                    "height": "100%",
                }
            )
        ],
        style={"height": "100%"}
    ),
    html.Div(
        id="explorer-panel",
        children=[
            dmc.Stack([
                dmc.Text("EXPLORER", size="xs", fw=700, c="dimmed"),
                dmc.NavLink(label="src", leftSection=DashIconify(icon="mdi:folder", color="yellow")),
                dmc.NavLink(label="app.py", leftSection=DashIconify(icon="mdi:file-code", color="blue")),
                dmc.NavLink(label="README.md", leftSection=DashIconify(icon="mdi:file-document")),
            ], p="sm", gap="xs")
        ],
        style={"height": "100%"}
    ),
]

component = dmc.Paper(
    DashDockLayout(
        id="dock-demo",
        panels=[
            {"id": "editor-panel", "title": "Editor", "position": "center"},
            {"id": "console-panel", "title": "Console", "position": "bottom", "size": 150},
            {"id": "explorer-panel", "title": "Explorer", "position": "left", "size": 200},
        ],
        children=panel_contents,
        theme="dockview-theme-dark",
        height="400px",
        showAddButton=False,
    ),
    withBorder=True,
    radius="md",
    p=4,
)
```


---

### Layout Components

Dash Dock View provides four distinct layout components for different use cases:

#### 1. DashDockLayout

Full-featured docking system with tabs, floating panels, and drag-and-drop. Ideal for IDE-style interfaces.

```python
from dash_dock_view import DashDockLayout

DashDockLayout(
    id="my-dock",
    panels=[
        {"id": "panel-1", "title": "Editor", "position": "center"},
        {"id": "panel-2", "title": "Console", "position": "bottom", "size": 200},
        {"id": "panel-3", "title": "Explorer", "position": "left", "size": 250},
    ],
    children=[
        html.Div(id="panel-1", children="Main content"),
        html.Div(id="panel-2", children="Console output"),
        html.Div(id="panel-3", children="File explorer"),
    ],
    theme="dockview-theme-dark",
    height="600px",
)
```

#### 2. DashGridLayout

Grid-based resizable panel system for structured layouts.



```python
# File: docs/dash_dock_view/gridlayout_example.py

"""DashGridLayout example for Dock View documentation."""
from dash import html
import dash_mantine_components as dmc
from dash_dock_view import DashGridLayout

# Sample data for chart
chart_data = [
    {"month": "Jan", "value": 1200},
    {"month": "Feb", "value": 1900},
    {"month": "Mar", "value": 1600},
    {"month": "Apr", "value": 2100},
    {"month": "May", "value": 1800},
]

# Panel contents
panel_contents = [
    html.Div(
        id="grid-chart-panel",
        children=[
            dmc.BarChart(
                h="100%",
                data=chart_data,
                dataKey="month",
                series=[{"name": "value", "color": "blue.6"}],
                withLegend=True,
            )
        ],
        style={"height": "100%", "padding": "1rem"}
    ),
    html.Div(
        id="grid-info-panel",
        children=[
            dmc.Stack([
                dmc.Title("Grid Layout", order=4),
                dmc.Text("Resize panels by dragging the divider.", c="dimmed", size="sm"),
                dmc.Divider(my="md"),
                dmc.Text("Features:", fw=600, size="sm"),
                dmc.List([
                    dmc.ListItem("Horizontal or vertical orientation"),
                    dmc.ListItem("Proportional resizing"),
                    dmc.ListItem("Customizable panel sizes"),
                ], size="sm"),
            ], p="md")
        ],
        style={"height": "100%"}
    ),
]

component = dmc.Paper(
    DashGridLayout(
        id="grid-demo",
        panels=[
            {"id": "grid-chart-panel", "size": 300},
            {"id": "grid-info-panel", "size": 200},
        ],
        children=panel_contents,
        theme="dockview-theme-dark",
        height="300px",
        orientation="horizontal",
        proportionalLayout=True,
    ),
    withBorder=True,
    radius="md",
    p=4,
)
```


#### 3. DashSplitLayout

Simple split panel layout with horizontal or vertical orientation.

```python
from dash_dock_view import DashSplitLayout

DashSplitLayout(
    id="my-split",
    panels=[
        {"id": "left-panel", "size": 300},
        {"id": "right-panel"},
    ],
    children=[
        html.Div(id="left-panel", children="Left content"),
        html.Div(id="right-panel", children="Right content"),
    ],
    orientation="horizontal",  # or "vertical"
    height="400px",
)
```

#### 4. DashPaneLayout

Collapsible accordion-style panes for organized content.

```python
from dash_dock_view import DashPaneLayout

DashPaneLayout(
    id="my-panes",
    panels=[
        {"id": "pane-1", "title": "Section 1", "collapsed": False},
        {"id": "pane-2", "title": "Section 2", "collapsed": True},
    ],
    children=[
        html.Div(id="pane-1", children="Content 1"),
        html.Div(id="pane-2", children="Content 2"),
    ],
    height="400px",
)
```

---

### Panel Configuration

Each panel in the layout can be configured with the following options:

| Property | Type | Default | Description |
|:---------|:-----|:--------|:------------|
| **`id`** | `string` | **Required** | Unique panel identifier (must match child component id) |
| `title` | `string` | id value | Display title in the tab |
| `position` | `string` | `'center'` | Position: `'left'`, `'right'`, `'top'`, `'bottom'`, `'center'` |
| `size` | `number` | auto | Initial size in pixels |
| `visible` | `boolean` | `True` | Whether panel is visible |
| `active` | `boolean` | `False` | Whether panel is active on load |
| `collapsed` | `boolean` | `False` | Start collapsed (click to expand) |

**Position Examples:**

```python
panels = [
    {"id": "editor", "title": "Editor", "position": "center"},      # Main area
    {"id": "explorer", "title": "Explorer", "position": "left", "size": 250},  # Left sidebar
    {"id": "console", "title": "Console", "position": "bottom", "size": 150},  # Bottom panel
    {"id": "props", "title": "Properties", "position": "right", "size": 200},  # Right sidebar
]
```

---

### Theming

Dash Dock View supports four built-in themes including Apple's Liquid Glass design.



```python
# File: docs/dash_dock_view/themes_example.py

"""
Liquid Glass Themes Example for Dash Dock View
================================================
Showcases Apple WWDC 2025 inspired liquid glass design with light/dark themes.
"""
from dash import callback, Input, Output
import dash_mantine_components as dmc
from dash_iconify import DashIconify
from dash_dock_view import DashDockLayout

# Inline style definitions for glass effects
GLASS_PANEL_STYLE_DARK = {
    "backdropFilter": "blur(20px) saturate(180%)",
    "WebkitBackdropFilter": "blur(20px) saturate(180%)",
    "background": "linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.05) 100%)",
    "border": "1px solid rgba(255, 255, 255, 0.15)",
    "boxShadow": "0 8px 32px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)",
    "borderRadius": "12px",
    "transition": "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
}

GLASS_PANEL_STYLE_LIGHT = {
    "backdropFilter": "blur(20px) saturate(180%)",
    "WebkitBackdropFilter": "blur(20px) saturate(180%)",
    "background": "linear-gradient(135deg, rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0.5) 100%)",
    "border": "1px solid rgba(255, 255, 255, 0.5)",
    "boxShadow": "0 8px 32px rgba(31, 38, 135, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.8)",
    "borderRadius": "12px",
    "transition": "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
}

FEATURE_CARD_STYLE_DARK = {
    "backdropFilter": "blur(16px) saturate(160%)",
    "WebkitBackdropFilter": "blur(16px) saturate(160%)",
    "background": "rgba(45, 55, 72, 0.6)",
    "border": "1px solid rgba(255, 255, 255, 0.1)",
    "borderRadius": "10px",
    "padding": "1rem",
    "transition": "all 0.3s ease",
}

FEATURE_CARD_STYLE_LIGHT = {
    "backdropFilter": "blur(16px) saturate(160%)",
    "WebkitBackdropFilter": "blur(16px) saturate(160%)",
    "background": "rgba(255, 255, 255, 0.7)",
    "border": "1px solid rgba(0, 0, 0, 0.05)",
    "borderRadius": "10px",
    "padding": "1rem",
    "transition": "all 0.3s ease",
}

STAT_BADGE_STYLE_DARK = {
    "backdropFilter": "blur(8px)",
    "WebkitBackdropFilter": "blur(8px)",
    "background": "rgba(79, 195, 247, 0.2)",
    "border": "1px solid rgba(79, 195, 247, 0.3)",
    "borderRadius": "20px",
    "padding": "0.5rem 1rem",
}

STAT_BADGE_STYLE_LIGHT = {
    "backdropFilter": "blur(8px)",
    "WebkitBackdropFilter": "blur(8px)",
    "background": "rgba(79, 195, 247, 0.15)",
    "border": "1px solid rgba(79, 195, 247, 0.25)",
    "borderRadius": "20px",
    "padding": "0.5rem 1rem",
}


def create_overview_panel(theme="dark"):
    """Create overview panel with theme switcher."""
    glass_style = GLASS_PANEL_STYLE_DARK if theme == "dark" else GLASS_PANEL_STYLE_LIGHT
    stat_badge_style = STAT_BADGE_STYLE_DARK if theme == "dark" else STAT_BADGE_STYLE_LIGHT

    return dmc.Box(
        id="lg-overview-panel",
        p="lg",
        style={**glass_style, "height": "100%", "overflow": "auto"},
        children=[
            dmc.Stack(
                gap="md",
                children=[
                    dmc.Group(
                        justify="space-between",
                        children=[
                            dmc.Group(
                                gap="sm",
                                children=[
                                    DashIconify(icon="mdi:palette-advanced", width=32, color="#4FC3F7"),
                                    dmc.Stack(
                                        gap=0,
                                        children=[
                                            dmc.Title("Liquid Glass", order=3),
                                            dmc.Text("Apple WWDC 2025", size="xs", c="dimmed"),
                                        ]
                                    ),
                                ]
                            ),
                            dmc.SegmentedControl(
                                id="lg-theme-switcher",
                                data=[
                                    {"value": "dark", "label": "🌙 Dark"},
                                    {"value": "light", "label": "☀️ Light"},
                                ],
                                value=theme,
                                color="blue",
                                radius="lg",
                            ),
                        ]
                    ),
                    dmc.Divider(opacity=0.2),
                    dmc.Text(
                        "Experience the next generation of UI design with glassmorphism effects, backdrop blur, and translucent layers.",
                        size="sm",
                        c="dimmed",
                    ),
                    dmc.Group(
                        gap="xs",
                        children=[
                            dmc.Box(dmc.Badge("Backdrop Blur", variant="dot", color="cyan"), style=stat_badge_style),
                            dmc.Box(dmc.Badge("Translucency", variant="dot", color="violet"), style=stat_badge_style),
                            dmc.Box(dmc.Badge("Gradients", variant="dot", color="orange"), style=stat_badge_style),
                        ]
                    ),
                ]
            )
        ]
    )


def create_features_panel(theme="dark"):
    """Create features showcase panel."""
    feature_style = FEATURE_CARD_STYLE_DARK if theme == "dark" else FEATURE_CARD_STYLE_LIGHT

    return dmc.Box(
        id="lg-features-panel",
        p="md",
        style={"height": "100%", "overflow": "auto"},
        children=[
            dmc.Stack(
                gap="sm",
                children=[
                    dmc.Title("Key Features", order=5, mb="xs"),
                    dmc.Box(
                        style=feature_style,
                        children=[
                            dmc.Group(
                                gap="sm",
                                mb="xs",
                                children=[
                                    DashIconify(icon="mdi:blur", width=20, color="#4FC3F7"),
                                    dmc.Text("Backdrop Blur", fw=600, size="sm"),
                                ]
                            ),
                            dmc.Text(
                                "Advanced blur effects with 20px radius and 180% saturation for ultra-realistic glass.",
                                size="xs",
                                c="dimmed",
                            ),
                        ]
                    ),
                    dmc.Box(
                        style=feature_style,
                        children=[
                            dmc.Group(
                                gap="sm",
                                mb="xs",
                                children=[
                                    DashIconify(icon="mdi:opacity", width=20, color="#9C27B0"),
                                    dmc.Text("Transparency", fw=600, size="sm"),
                                ]
                            ),
                            dmc.Text(
                                "Layered semi-transparent gradients that adapt to light and dark modes.",
                                size="xs",
                                c="dimmed",
                            ),
                        ]
                    ),
                    dmc.Box(
                        style=feature_style,
                        children=[
                            dmc.Group(
                                gap="sm",
                                mb="xs",
                                children=[
                                    DashIconify(icon="mdi:gradient-vertical", width=20, color="#FFC107"),
                                    dmc.Text("Liquid Borders", fw=600, size="sm"),
                                ]
                            ),
                            dmc.Text(
                                "Animated gradient borders with smooth 8s infinite animation cycles.",
                                size="xs",
                                c="dimmed",
                            ),
                        ]
                    ),
                ]
            )
        ]
    )


def create_controls_panel(theme="dark"):
    """Create interactive controls panel."""
    glass_style = GLASS_PANEL_STYLE_DARK if theme == "dark" else GLASS_PANEL_STYLE_LIGHT

    return dmc.Box(
        id="lg-controls-panel",
        p="md",
        style={**glass_style, "height": "100%", "overflow": "auto"},
        children=[
            dmc.Stack(
                gap="md",
                children=[
                    dmc.Title("Controls", order=5),
                    dmc.Text("Interact with glass-style components:", size="xs", c="dimmed", mb="xs"),
                    dmc.Group(
                        gap="xs",
                        children=[
                            dmc.Button(
                                "Primary",
                                size="sm",
                                variant="light",
                                color="blue",
                                leftSection=DashIconify(icon="mdi:cursor-default-click", width=16),
                            ),
                            dmc.Button(
                                "Success",
                                size="sm",
                                variant="light",
                                color="green",
                                leftSection=DashIconify(icon="mdi:check-circle", width=16),
                            ),
                        ]
                    ),
                    dmc.Divider(opacity=0.2),
                    dmc.Slider(
                        id="lg-demo-slider",
                        value=65,
                        min=0,
                        max=100,
                        marks=[
                            {"value": 0, "label": "0%"},
                            {"value": 50, "label": "50%"},
                            {"value": 100, "label": "100%"},
                        ],
                        mb="xl",
                        color="cyan",
                    ),
                    dmc.Switch(
                        id="lg-demo-switch",
                        label="Enable animations",
                        checked=True,
                        size="md",
                        color="violet",
                    ),
                ]
            )
        ]
    )


def create_metrics_panel(theme="dark"):
    """Create metrics panel with glass effect."""
    feature_style = FEATURE_CARD_STYLE_DARK if theme == "dark" else FEATURE_CARD_STYLE_LIGHT

    return dmc.Box(
        id="lg-metrics-panel",
        p="md",
        style={"height": "100%", "overflow": "auto"},
        children=[
            dmc.Stack(
                gap="lg",
                children=[
                    dmc.Title("Metrics", order=5),
                    dmc.Stack(
                        gap="md",
                        children=[
                            dmc.Box(
                                style=feature_style,
                                children=[
                                    dmc.Group(
                                        justify="space-between",
                                        children=[
                                            dmc.Stack(
                                                gap=0,
                                                children=[
                                                    dmc.Text("Blur Radius", size="xs", c="dimmed"),
                                                    dmc.Title("20px", order=4, c="cyan"),
                                                ]
                                            ),
                                            DashIconify(icon="mdi:blur-radial", width=32, color="#4FC3F7", style={"opacity": 0.6}),
                                        ]
                                    ),
                                ]
                            ),
                            dmc.Box(
                                style=feature_style,
                                children=[
                                    dmc.Group(
                                        justify="space-between",
                                        children=[
                                            dmc.Stack(
                                                gap=0,
                                                children=[
                                                    dmc.Text("Saturation", size="xs", c="dimmed"),
                                                    dmc.Title("180%", order=4, c="violet"),
                                                ]
                                            ),
                                            DashIconify(icon="mdi:palette", width=32, color="#9C27B0", style={"opacity": 0.6}),
                                        ]
                                    ),
                                ]
                            ),
                            dmc.Box(
                                style=feature_style,
                                children=[
                                    dmc.Group(
                                        justify="space-between",
                                        children=[
                                            dmc.Stack(
                                                gap=0,
                                                children=[
                                                    dmc.Text("Opacity", size="xs", c="dimmed"),
                                                    dmc.Title("65%", order=4, c="orange"),
                                                ]
                                            ),
                                            DashIconify(icon="mdi:opacity", width=32, color="#FFC107", style={"opacity": 0.6}),
                                        ]
                                    ),
                                ]
                            ),
                        ]
                    ),
                ]
            )
        ]
    )


def create_code_panel(theme="dark"):
    """Create code preview panel."""
    glass_style = GLASS_PANEL_STYLE_DARK if theme == "dark" else GLASS_PANEL_STYLE_LIGHT

    return dmc.Box(
        id="lg-code-panel",
        p="md",
        style={**glass_style, "height": "100%", "overflow": "auto"},
        children=[
            dmc.Stack(
                gap="sm",
                children=[
                    dmc.Group(
                        justify="space-between",
                        children=[
                            dmc.Title("CSS Preview", order=5),
                            dmc.ActionIcon(
                                DashIconify(icon="mdi:content-copy", width=16),
                                variant="subtle",
                                color="gray",
                                size="sm",
                            ),
                        ]
                    ),
                    dmc.Code(
                        block=True,
                        children="""backdrop-filter: blur(20px) saturate(180%);
background: linear-gradient(
  135deg,
  rgba(255, 255, 255, 0.08) 0%,
  rgba(255, 255, 255, 0.05) 100%
);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow:
  0 8px 32px rgba(0, 0, 0, 0.5),
  inset 0 1px 0 rgba(255, 255, 255, 0.1);""",
                        style={"fontSize": "11px"},
                    ),
                ]
            )
        ]
    )


# Main component
component = dmc.Box(
    id="liquid-glass-demo-container",
    style={
        "background": "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)",
        "borderRadius": "16px",
        "padding": "4px",
        "position": "relative",
        "transition": "background 0.3s ease",
    },
    children=[
        DashDockLayout(
            id="lg-dock-layout",
            panels=[
                {"id": "lg-overview-panel", "title": "Overview", "closeable": False},
                {"id": "lg-features-panel", "title": "Features", "closeable": False},
                {"id": "lg-controls-panel", "title": "Controls", "closeable": False},
                {"id": "lg-metrics-panel", "title": "Metrics", "closeable": False},
                {"id": "lg-code-panel", "title": "Code", "closeable": False},
            ],
            children=[
                create_overview_panel("dark"),
                create_features_panel("dark"),
                create_controls_panel("dark"),
                create_metrics_panel("dark"),
                create_code_panel("dark"),
            ],
            theme="dockview-theme-liquid-glass-dark",
            height="450px",
            showAddButton=False,
        ),
    ]
)


# Callback to switch themes
@callback(
    Output("liquid-glass-demo-container", "style"),
    Output("lg-dock-layout", "theme"),
    Output("lg-dock-layout", "children"),
    Input("lg-theme-switcher", "value"),
)
def switch_liquid_glass_theme(theme_value):
    """Toggle between liquid glass light and dark themes."""
    if theme_value == "light":
        container_style = {
            "background": "linear-gradient(135deg, #e8f4f8 0%, #d4e5f7 50%, #c1d5eb 100%)",
            "borderRadius": "16px",
            "padding": "4px",
            "position": "relative",
            "transition": "background 0.3s ease",
        }
        return (
            container_style,
            "dockview-theme-liquid-glass-light",
            [
                create_overview_panel("light"),
                create_features_panel("light"),
                create_controls_panel("light"),
                create_metrics_panel("light"),
                create_code_panel("light"),
            ]
        )
    else:
        container_style = {
            "background": "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)",
            "borderRadius": "16px",
            "padding": "4px",
            "position": "relative",
            "transition": "background 0.3s ease",
        }
        return (
            container_style,
            "dockview-theme-liquid-glass-dark",
            [
                create_overview_panel("dark"),
                create_features_panel("dark"),
                create_controls_panel("dark"),
                create_metrics_panel("dark"),
                create_code_panel("dark"),
            ]
        )
```


**Available Themes:**

| Theme | Class Name | Description |
|:------|:-----------|:------------|
| Light | `dockview-theme-light` | Classic light theme |
| Dark | `dockview-theme-dark` | Classic dark theme |
| Liquid Glass Light | `dockview-theme-liquid-glass-light` | Apple glassmorphism (light) |
| Liquid Glass Dark | `dockview-theme-liquid-glass-dark` | Apple glassmorphism (dark) |

**Applying Themes:**

```python
DashDockLayout(
    id="my-dock",
    panels=[...],
    children=[...],
    theme="dockview-theme-liquid-glass-dark",  # Apply theme
    height="500px",
)
```

**Liquid Glass CSS Variables:**

```css
.dockview-theme-liquid-glass-dark {
    --dv-background-color: rgba(30, 30, 30, 0.65);
    --dv-foreground-color: rgba(255, 255, 255, 0.95);
    --dv-separator-border: rgba(255, 255, 255, 0.12);
}

.dockview-theme-liquid-glass-dark .dv-dockview {
    backdrop-filter: blur(16px) saturate(180%);
    border-radius: 12px;
}
```

---

### Layout Persistence

Save and restore layout configurations using the `layout` property.

```python
from dash import callback, Input, Output, State
import json

# Save layout
@callback(
    Output("layout-store", "data"),
    Input("dock-layout", "layout"),
)
def save_layout(layout):
    return json.dumps(layout) if layout else None

# Restore layout
@callback(
    Output("dock-layout", "layout"),
    Input("restore-btn", "n_clicks"),
    State("layout-store", "data"),
    prevent_initial_call=True,
)
def restore_layout(n_clicks, saved_layout):
    if saved_layout:
        return json.loads(saved_layout)
    return dash.no_update
```

---

### Callbacks and Interactivity

Dash Dock View components integrate seamlessly with Dash callbacks.

**Available Callback Properties:**

- **`activePanel`**: Currently active panel id
- **`panelCount`**: Number of visible panels
- **`layout`**: Current layout configuration (JSON)

```python
@callback(
    Output("active-display", "children"),
    Output("count-display", "children"),
    Input("dock-layout", "activePanel"),
    Input("dock-layout", "panelCount"),
)
def update_info(active_panel, panel_count):
    return f"Active: {active_panel}", f"Count: {panel_count}"
```

---

### Component Properties

#### DashDockLayout

| Property | Type | Default | Description |
|:---------|:-----|:--------|:------------|
| **`id`** | `string` | **Required** | Unique component identifier |
| **`panels`** | `array` | **Required** | Panel configurations |
| **`children`** | `node` | **Required** | Dash components for panels |
| `theme` | `string` | `'dockview-theme-light'` | Theme class name |
| `height` | `string` | `'600px'` | Container height |
| `locked` | `boolean` | `False` | Lock layout modifications |
| `gap` | `number` | `0` | Gap between split panels |
| `showAddButton` | `boolean` | `True` | Show add panel button |
| `disableDnd` | `boolean` | `False` | Disable drag-and-drop |
| `disableFloatingGroups` | `boolean` | `False` | Disable floating windows |
| `hideBorders` | `boolean` | `False` | Hide panel borders |
| `singleTabMode` | `string` | `'default'` | Tab display mode: `'default'` or `'fullwidth'` |
| `activePanel` | `string` | Read-only | Currently active panel id |
| `panelCount` | `number` | Read-only | Number of visible panels |
| `layout` | `object` | Read-only | Current layout configuration |

#### DashGridLayout

| Property | Type | Default | Description |
|:---------|:-----|:--------|:------------|
| **`id`** | `string` | **Required** | Unique component identifier |
| **`panels`** | `array` | **Required** | Panel configurations |
| **`children`** | `node` | **Required** | Dash components for panels |
| `theme` | `string` | `'dockview-theme-light'` | Theme class name |
| `height` | `string` | `'600px'` | Container height |
| `orientation` | `string` | `'horizontal'` | Layout orientation: `'horizontal'` or `'vertical'` |
| `proportionalLayout` | `boolean` | `True` | Maintain proportions on resize |

#### DashSplitLayout

| Property | Type | Default | Description |
|:---------|:-----|:--------|:------------|
| **`id`** | `string` | **Required** | Unique component identifier |
| **`panels`** | `array` | **Required** | Panel configurations (2 panels) |
| **`children`** | `node` | **Required** | Dash components for panels |
| `theme` | `string` | `'dockview-theme-light'` | Theme class name |
| `height` | `string` | `'400px'` | Container height |
| `orientation` | `string` | `'horizontal'` | Split orientation |

#### DashPaneLayout

| Property | Type | Default | Description |
|:---------|:-----|:--------|:------------|
| **`id`** | `string` | **Required** | Unique component identifier |
| **`panels`** | `array` | **Required** | Panel configurations |
| **`children`** | `node` | **Required** | Dash components for panels |
| `theme` | `string` | `'dockview-theme-light'` | Theme class name |
| `height` | `string` | `'400px'` | Container height |

---

### Dynamic Props vs Construction Props

Some props can be updated dynamically, while others require recreating the component:

**Dynamic Props (Live Update):**
- `locked`, `gap`, `disableDnd`, `disableFloatingGroups`, `showAddButton`, `height`

**Construction Props (Require Reset):**
- `hideBorders`, `singleTabMode`, `panels`

```python
# Dynamic prop update - works instantly
@callback(
    Output("dock-layout", "locked"),
    Input("lock-switch", "checked"),
)
def toggle_lock(checked):
    return checked

# Construction prop - requires component recreation
@callback(
    Output("dock-container", "children"),
    Input("apply-btn", "n_clicks"),
    State("hide-borders-switch", "checked"),
)
def apply_construction_props(n_clicks, hide_borders):
    return DashDockLayout(
        id="dock-layout",
        panels=[...],
        children=[...],
        hideBorders=hide_borders,  # Requires fresh component
    )
```

---

### Best Practices

1. **Match Panel IDs**: Ensure each panel's `id` matches the corresponding child component's `id`

```python
panels = [{"id": "my-panel", "title": "My Panel"}]
children = [html.Div(id="my-panel", children="Content")]  # IDs must match!
```

2. **Set Explicit Height**: Always set a height for the container

```python
DashDockLayout(
    ...,
    height="600px",  # or "80vh"
)
```

3. **Use Theme-Aware Backgrounds**: For Liquid Glass themes, use gradient backgrounds

```python
html.Div(
    DashDockLayout(..., theme="dockview-theme-liquid-glass-dark"),
    style={
        "background": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
        "borderRadius": "16px",
        "padding": "4px",
    }
)
```

4. **Prevent Initial Callbacks**: Use `prevent_initial_call=True` for callbacks that respond to user interactions

---

### Troubleshooting

**Issue: Panel content not appearing**

**Solution:** Ensure the panel `id` matches the child component's `id` exactly.

**Issue: Layout not filling container**

**Solution:** Set an explicit `height` prop (e.g., `"600px"` or `"80vh"`).

**Issue: Theme not applying correctly**

**Solution:** Make sure you're using the correct theme class name and the component is wrapped appropriately for glass themes.

**Issue: Drag and drop not working**

**Solution:** Check that `disableDnd` is not set to `True` and `locked` is `False`.

---

### Contributing

Contributions to dash-dock-view 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://2plot.dev) and licensed under the MIT License.
