API Reference

Components

Prism

class dash_prism.Prism(id: str | None = _UNSET, className: str | None = _UNSET, style: dict[str, Any] | None = _UNSET, theme: Literal['light', 'dark'] = _UNSET, size: Literal['sm', 'md', 'lg'] = _UNSET, actions: Sequence[Component] | None = _UNSET, statusBarPosition: Literal['top', 'bottom'] = _UNSET, persistence: bool = _UNSET, persistence_type: Literal['memory', 'session', 'local'] = _UNSET, maxTabs: int = _UNSET, initialLayout: str | None = _UNSET, newTabOpensDropdown: bool = _UNSET, searchBarPlaceholder: str = _UNSET, layoutTimeout: int = _UNSET, children: list[Component] | None = _UNSET, serverSessionId: str | None = _UNSET, registeredLayouts: dict[str, Any] | None = _UNSET, readWorkspace: dict[str, Any] | None = _UNSET, updateWorkspace: dict[str, Any] | None = _UNSET, **kwargs: Any)[source]

Bases: PrismComponent

Advanced multi-panel workspace manager for Plotly Dash.

Prism provides a powerful tabbed workspace with drag-and-drop functionality, allowing users to create, organize, and manage multiple layouts in a single application. It supports multi-panel splits, persistent state, and dynamic layout loading with full async support.

Features:

  • Dynamic Tab Management: Create, close, rename, and reorder tabs

  • Multi-Panel Layouts: Split workspace into multiple panels via drag-and-drop

  • Persistent State: Save workspace configuration across browser sessions

  • Layout Registry: Register static or dynamic layouts with parameters

  • Async Support: Full support for async layout callbacks

  • Type-Safe: Complete type hints for Python 3.10+

Parameters:
  • id (str or None) – Unique identifier for this component in Dash callbacks. Use this ID to read workspace state or update component properties.

  • serverSessionId (str or None) – Server session identifier used to invalidate stale persisted workspaces after server restarts. Automatically set by dash_prism.init() unless explicitly provided.

  • theme (str) – Visual theme for the workspace. Controls colors, backgrounds, and overall appearance. Defaults to 'light'.

  • size (str) – Size variant affecting spacing, typography, and UI element sizing. Options: 'sm' (small), 'md' (medium, default), 'lg' (large). Defaults to 'md'.

  • maxTabs (int) – Maximum number of tabs allowed in the workspace. Prevents users from creating too many tabs which could impact performance. Values less than 1 (e.g., 0 or -1) mean unlimited tabs. Defaults to 16.

  • searchBarPlaceholder (str) – Placeholder text shown in the layout search bar. Defaults to 'Search layouts...'.

  • layoutTimeout (int) – Timeout in seconds for layout loading. If a layout callback doesn’t respond within this time, an error state is shown. Defaults to 30.

  • statusBarPosition (str) – Position of the status bar relative to the workspace. Options: 'top' or 'bottom'. Defaults to 'bottom'.

  • actions (list[Action] or None) – Array of Action components to display in the status bar. Each action is a clickable button with its own n_clicks for callbacks.

  • persistence (bool) – If True, workspace state is persisted across browser sessions. The persistence method is controlled by persistence_type. Defaults to False.

  • persistence_type (str) – Where to persist workspace state. Options: 'local' (localStorage, persists across browser sessions), 'session' (sessionStorage, persists only for current tab session), 'memory' (no persistence, state lost on page refresh). Defaults to 'memory'.

  • initialLayout (str or None) – Layout ID to automatically load in the first tab on initial page load. Must match a layout registered via dash_prism.register_layout() before calling dash_prism.init(). Only applies on the very first load; if persistence is enabled and a saved workspace exists, the persisted state takes precedence.

  • newTabOpensDropdown (bool) – Whether opening a new tab should automatically focus the SearchBar and open the layout dropdown. If True (default), new tabs instantly show the layout dropdown for quick selection. If False, users must click the SearchBar to see available layouts.

  • readWorkspace (dict or None) – Read-only workspace state. Use as an Input or State in Dash callbacks to react to workspace changes. The workspace dict contains: tabs (list of dict), panel (dict), activePanelId (str), activeTabIds (dict).

  • updateWorkspace (dict or None) – Write-only workspace state. Use as an Output in Dash callbacks to programmatically update the workspace. Partial updates are supported.

  • children (list or None) – Child components (typically PrismContent instances). Advanced - Usually managed automatically by dash_prism.init().

  • registeredLayouts (dict or None) – Registry of available layouts that can be rendered in tabs. Advanced - Automatically populated by dash_prism.init().

  • className (str or None) – CSS class name(s) to add to the root container. Appended to Prism’s internal classes. Useful for custom sizing or layout.

  • style (dict or None) – Inline CSS styles for the root container.

Examples

Basic usage with registered layouts:

import dash_prism
from dash import Dash, html

app = Dash(__name__)

# Register layouts
@dash_prism.register_layout(id='home', name='Home')
def home_layout():
    return html.Div('Welcome to Prism!')

@dash_prism.register_layout(id='about', name='About')
def about_layout():
    return html.Div('About page')

# Create app layout
app.layout = html.Div([
    dash_prism.Prism(
        id='workspace',
        theme='light',
        maxTabs=10,
        persistence=True,
        persistence_type='local',
    )
])

# Initialize Prism (injects layouts and creates callbacks)
dash_prism.init('workspace', app)

if __name__ == '__main__':
    app.run_server(debug=True)

With status bar actions:

from dash import Input, Output

app.layout = html.Div([
    dash_prism.Prism(
        id='workspace',
        actions=[
            dash_prism.Action(
                id='save-btn',
                label='Save',
                icon='Save',
                tooltip='Save current workspace'
            ),
            dash_prism.Action(
                id='export-btn',
                label='Export',
                icon='Download',
                tooltip='Export workspace data'
            ),
        ],
    )
])

@app.callback(
    Output('save-btn', 'loading'),
    Input('save-btn', 'n_clicks'),
    prevent_initial_call=True
)
def handle_save(n_clicks):
    # Perform save operation
    return False  # Stop loading spinner

Reading workspace state:

@app.callback(
    Output('workspace-info', 'children'),
    Input('workspace', 'readWorkspace')
)
def display_workspace_info(workspace):
    if not workspace:
        return "No workspace data"

    num_tabs = len(workspace.get('tabs', []))
    active_panel = workspace.get('activePanelId', 'none')

    return f"Tabs: {num_tabs}, Active Panel: {active_panel}"

See also

Action

Action button component for the status bar

dash_prism.register_layout()

Decorator/function to register layouts

dash_prism.init()

Initialize Prism with Dash app

Note

  • This component requires initialization via dash_prism.init()

  • Layouts must be registered before calling init()

  • The workspace state is managed internally and synced with Dash via callbacks

  • For best performance, limit maxTabs to a reasonable number (8-12)

Action

class dash_prism.Action(label: str = _UNSET, id: str | None = _UNSET, tooltip: str | None = _UNSET, variant: str | None = _UNSET, disabled: bool = _UNSET, loading: bool = _UNSET, n_clicks: int = _UNSET, **kwargs: Any)[source]

Bases: PrismActionComponent

A clickable action button for the Prism status bar.

Action components are displayed in the status bar and provide interactive buttons that users can click to trigger callbacks. Each action is an independent Dash component with its own n_clicks property, allowing for individual callback handling per button.

Parameters:
  • id (str or None) – Unique identifier for this action in Dash callbacks. Use this ID to create callbacks responding to button clicks.

  • label (str) – Button label text displayed in the status bar. This is the visible text users will see on the button. Required.

  • tooltip (str or None) – Tooltip text shown on hover. If not provided, defaults to "Click to trigger {label}".

  • variant (str or None) – Button style variant or custom hex color. Preset variants: 'default', 'primary', 'secondary', 'success', 'warning', 'danger'. Custom color: Any valid hex color (e.g., '#FF5500').

  • disabled (bool) – Whether the button is disabled. Disabled buttons cannot be clicked and appear grayed out. Can be controlled via Dash callbacks for dynamic enabling/disabling. Defaults to False.

  • loading (bool) – Whether to show a loading spinner. When True, replaces the icon with a spinner and disables the button. Useful for indicating async operations are in progress. Defaults to False.

  • n_clicks (int) – Number of times the button has been clicked. Use as an Input in Dash callbacks to respond to clicks. Automatically incremented each time the button is clicked. Defaults to 0.

Examples

Basic action button:

import dash_prism
from dash import Dash, html, Input, Output

app = Dash(__name__)

app.layout = html.Div([
    dash_prism.Prism(
        id='workspace',
        actions=[
            dash_prism.Action(
                id='save-action',
                label='Save',
                tooltip='Save current workspace'
            )
        ]
    )
])

@app.callback(
    Output('save-action', 'loading'),
    Input('save-action', 'n_clicks'),
    prevent_initial_call=True
)
def handle_save(n_clicks):
    # Perform save operation
    import time
    time.sleep(1)  # Simulate async operation
    return False  # Stop loading spinner

Multiple actions with different styles:

actions = [
    dash_prism.Action(
        id='save',
        label='Save',
        variant='primary'
    ),
    dash_prism.Action(
        id='export',
        label='Export',
        variant='secondary'
    ),
    dash_prism.Action(
        id='delete',
        label='Delete All',
        variant='danger',
        tooltip='WARNING: This will delete all data'
    ),
]

app.layout = html.Div([
    dash_prism.Prism(id='workspace', actions=actions)
])

Dynamic enabling/disabling:

from dash import State

@app.callback(
    Output('save-action', 'disabled'),
    Input('workspace', 'readWorkspace')
)
def update_save_button(workspace):
    # Disable save button if no tabs are open
    if not workspace or not workspace.get('tabs'):
        return True  # Disabled
    return False  # Enabled

Custom color action:

custom_action = dash_prism.Action(
    id='custom',
    label='Custom',
    variant='#FF5500',  # Custom orange color
    tooltip='Custom colored action'
)

Loading state management:

@app.callback(
    Output('export-action', 'loading'),
    Input('export-action', 'n_clicks'),
    prevent_initial_call=True
)
def handle_export(n_clicks):
    # Set loading=True while operation runs
    import time
    time.sleep(2)  # Simulate export operation
    return False  # Loading complete

See also

Prism

Main workspace component

dash_prism.init()

Initialize Prism with Dash app

Note

  • Actions must be passed to the Prism component’s actions parameter

  • Each action has an independent n_clicks counter

  • The loading state automatically disables the button

  • Custom hex colors must be valid CSS hex colors (e.g., #RGB or #RRGGBB)

Registration

dash_prism.register_layout(id: str, *, name: str | None = None, description: str = '', keywords: List[str] | None = None, allow_multiple: bool = False, param_options: Dict[str, Tuple[str, Dict[str, Any]]] | None = None, layout: Any) None[source]
dash_prism.register_layout(id: str, *, name: str | None = None, description: str = '', keywords: List[str] | None = None, allow_multiple: bool = False, param_options: Dict[str, Tuple[str, Dict[str, Any]]] | None = None) Callable[[Callable[[...], Any]], Callable[[...], Any]]

Register a layout with Prism.

Can be used in two ways:

Method A: Static Layout:

register_layout(
    id='home',
    name='Home',
    description='Welcome page',
    layout=html.Div([html.H1('Welcome!')])
)

Method B: Decorator:

@register_layout(
    id='chart',
    name='Chart View',
    param_options={
        'bar': ('Bar Chart', {'chart_type': 'bar'}),
        'line': ('Line Chart', {'chart_type': 'line'}),
    }
)
def chart_layout(chart_type: str = 'bar'):
    return dcc.Graph(...)
Parameters:
  • id (str) – Unique identifier for this layout (required).

  • name (str | None) – Human-readable display name. Defaults to id.

  • description (str) – Description shown in the layout picker.

  • keywords (list[str] | None) – Searchable keywords for finding this layout.

  • allow_multiple (bool) – Whether multiple instances can be open simultaneously. Defaults to False.

  • param_options (dict[str, tuple[str, dict[str, Any]]] | None) – Pre-defined parameter configurations. Format: {'key': ('Display Label', {'param': 'value'})}.

  • layout (Any | None) – Static Dash component tree (Method A only).

Returns:

None if registering a static layout, decorator function otherwise.

Return type:

None | Callable[[Callable[…, Any]], Callable[…, Any]]

Raises:

ValueError – If validation fails or layout is already registered.

Examples

Static registration:

>>> register_layout(
...     id='about',
...     name='About',
...     layout=html.Div('About page'),
... )

Decorator registration:

>>> @register_layout(id='home', name='Home')
... def home_layout():
...     return html.Div('Welcome!')
dash_prism.init(prism_id: str, app: Dash, background: bool = False) None[source]

Initialize Prism with a Dash application.

This function performs the following:

  1. Validates the setup and provides clear error messages

  2. Finds the Prism component in app.layout by ID

  3. Injects registeredLayouts metadata from the layout registry

  4. Creates the appropriate callback (sync or async) to render tab contents

The callback type is determined automatically:

  • If app has use_async=True, async callbacks are used

  • Otherwise, sync callbacks are used (async layouts run via asyncio.run())

Parameters

prism_idstr

The ID of the Prism component in the layout.

appDash

The Dash application instance.

backgroundbool, optional

If True, the tab rendering callback is registered with background=True so that Dash’s Background Callback Manager can execute it in a separate process (DiskCache) or on a task queue (Celery). Requires a background_callback_manager to be configured on the Dash app. Defaults to False.

Raises

InitializationError

If critical validation fails.

Examples

Basic usage:

>>> import dash_prism
>>> from dash import Dash, html
>>>
>>> app = Dash(__name__)
>>>
>>> @dash_prism.register_layout(id='home', name='Home')
... def home_layout():
...     return html.Div('Welcome!')
>>>
>>> app.layout = html.Div([
...     dash_prism.Prism(id='prism')
... ])
>>>
>>> dash_prism.init('prism', app)

With background callbacks:

>>> from dash import DiskcacheManager
>>> import diskcache
>>>
>>> cache = diskcache.Cache("./cache")
>>> background_callback_manager = DiskcacheManager(cache)
>>> app = Dash(__name__, background_callback_manager=background_callback_manager)
>>>
>>> dash_prism.init('prism', app, background=True)
class dash_prism.LayoutParameter(name: str, has_default: bool = False, default: Any = None, annotation: str | None = None)[source]

Bases: object

Describes a parameter for a parameterized layout callback.

Variables:
  • name – The parameter name.

  • has_default – Whether the parameter has a default value.

  • default – The default value, if any.

  • annotation – The type annotation as a string.

name: str
has_default: bool = False
default: Any = None
annotation: str | None = None
to_dict() Dict[str, Any][source]

Convert to a dictionary for JSON serialization.

Returns:

Dictionary with camelCase keys for frontend consumption.

Return type:

dict[str, Any]

dash_prism.get_layout(layout_id: str) LayoutRegistration | None[source]

Get a registered layout by ID.

Parameters:

layout_id (str) – The ID of the layout to retrieve.

Returns:

The registration if found, None otherwise.

Return type:

LayoutRegistration | None

dash_prism.clear_registry() None[source]

Clear all registered layouts.

Useful for testing to reset state between test cases.

Icons

dash_prism.get_available_icons() List[str][source]

Get a sorted list of available icon names.

These icons can be used with the icon parameter of Action and for tab icons in Prism. Icons are from a curated subset of lucide-react.

Returns:

Sorted list of available icon names.

Return type:

list[str]

Example

import dash_prism

# Print all available icons
for icon in dash_prism.get_available_icons():
    print(icon)

# Check if an icon is available
if 'Rocket' in dash_prism.AVAILABLE_ICONS:
    print('Rocket icon is available!')

See also

AVAILABLE_ICONS

Frozen set for membership testing.

Action

Action component that uses icons.

dash_prism.AVAILABLE_ICONS = frozenset(['Activity', 'Atom', 'Banana', 'Banknote', 'BarChart3', 'Beaker', 'Binary', 'Bitcoin', 'Bot', 'Brain', 'Bug', 'Calculator', 'Cat', 'CircuitBoard', 'Coffee', 'Coins', 'Cpu', 'Dog', 'DollarSign', 'Euro', 'FlaskConical', 'GitBranch', 'Globe', 'Heart', 'Infinity', 'JapaneseYen', 'Landmark', 'Lightbulb', 'LineChart', 'PieChart', 'PiggyBank', 'PoundSterling', 'Rocket', 'Sparkles', 'SwissFranc', 'TrendingDown', 'TrendingUp', 'TrendingUpDown', 'Trophy', 'Wallet', 'Zap'])

Lazy proxy for AVAILABLE_ICONS to defer file loading until first use.

Utilities

dash_prism.walk_layout(layout: Any, transform: Callable[[Any], Any], _visited: Set[int] | None = None) Any[source]

Recursively walk and transform a Dash component tree.

Parameters:
  • layout (Any) – The root component to transform.

  • transform (Callable[[Any], Any]) – Function called on each component. Receives a component and returns the transformed component.

Returns:

The transformed layout.

Return type:

Any

Example:

def add_class(component):
    if hasattr(component, 'className'):
        existing = component.className or ''
        component.className = f'{existing} my-class'.strip()
    return component

transformed = walk_layout(my_layout, add_class)
dash_prism.inject_tab_id(layout: Any, tab_id: str) Any[source]

Convert component IDs to pattern-matching format for tab isolation.

Transforms string IDs like 'my-input' into pattern-matching dicts:

{'type': 'my-input', 'index': tab_id}

Components that already have pattern-matching IDs (dicts) are left unchanged. Components without an ID are also left unchanged.

Parameters:
  • layout (Any) – The component tree to transform.

  • tab_id (str) – The tab ID to inject as the 'index' value.

Returns:

Layout with transformed IDs (deep copy).

Return type:

Any

Example:

layout = html.Div([
    dcc.Input(id='my-input'),
    html.Div(id='my-output'),
    html.Span(id={'type': 'existing', 'index': 'other'}),
])
injected = inject_tab_id(layout, 'tab-abc-123')
# String IDs become: {'type': 'my-input', 'index': 'tab-abc-123'}
# Dict IDs are left unchanged
dash_prism.find_component_by_id(layout: Any, component_id: str) Any | None[source]

Find a component by its ID in a layout tree.

Parameters:
  • layout (Any) – The root component to search.

  • component_id (str) – The ID to find.

Returns:

The component with matching ID, or None if not found.

Return type:

Any | None

dash_prism.update_component_props(layout: Any, component_id: str, **props: Any) Any[source]

Update properties of a component by ID.

Parameters:
  • layout (Any) – The root component tree.

  • component_id (str) – The ID of the component to update.

  • props (Any) – Properties to set on the component.

Returns:

The updated layout (deep copy).

Return type:

Any

Example:

layout = html.Div([
    dcc.Input(id='my-input', value='old'),
])
updated = update_component_props(layout, 'my-input', value='new')
dash_prism.validate_workspace(workspace: Dict[str, Any], errors: Literal['raise', 'ignore'] = 'raise') Dict[str, Any][source]

Validate that a dictionary is a valid Prism Workspace.

Checks cross-key consistency between tabs, panel, panelTabs, activeTabIds, and activePanelId to ensure the workspace state is coherent.

Parameters:
  • workspace (dict[str, Any]) – Dictionary to be validated as a Prism workspace.

  • errors (Literal['raise', 'ignore']) – Error handling mode. 'raise' raises InvalidWorkspace on failure, 'ignore' logs errors and returns anyway. Defaults to 'raise'.

Returns:

The validated workspace dictionary (unchanged).

Return type:

dict[str, Any]

Raises:

InvalidWorkspace – If errors='raise' and validation failed.

Example:

workspace = {
    'tabs': [{'id': 'tab1', 'name': 'Tab 1', 'panelId': 'panel1', 'createdAt': 123}],
    'panel': {'id': 'panel1', 'order': 0, 'direction': 'horizontal', 'children': []},
    'panelTabs': {'panel1': ['tab1']},
    'activeTabIds': {'panel1': 'tab1'},
    'activePanelId': 'panel1',
}
validate_workspace(workspace)  # Returns workspace if valid

Exceptions

class dash_prism.InitializationError[source]

Bases: Exception

Raised when Prism initialization fails.

class dash_prism.InvalidWorkspace(errors: List[str])[source]

Bases: Exception

Exception raised when workspace validation fails.

Variables:

errors – List of validation error messages describing what failed.