FlexLayout React

repository·master·Indexed 23 days ago

https://github.com/caplin/flexlayout

A multi-tab docking layout manager for React that allows users to organize components into complex, resizable, and draggable tabsets and rows. It supports advanced features such as popout windows, custom theming, and a JSON-based model for defining layout hierarchies including rows, tabsets, and borders.

Tokens
12.9K
Snippets
28
Records
61
Agent score
79%

What's inside flexlayout-react

  1. Understand the JSON Model structure

    master

    The layout is defined by a JSON model containing four top-level elements:

    • global: (Optional) Global options (e.g., rootOrientationVertical, tabSetEnableTabStrip).
    • layout: The main hierarchy of nodes. It is built using three types:
      • row: Contains a list of tabset nodes or child row nodes. Top-level rows render horizontally by default. Child rows render in the opposite orientation to their parent.
      • tabset: Contains a list of tab nodes and the index of the selected tab.
      • tab: Specifies the component to host (via the factory) and the tab's display text.
    • borders: (Optional) Up to four borders (top, bottom, left, right). Each border contains a list of tabs and a selected index.
    • subLayouts: (Optional) Defines layouts for popout windows, floating panels, and tabs.

    Weights: Weights on rows and tabsets specify their relative size. Absolute values do not matter, only their proportions.

  2. Install and run the FlexLayout demo

    master

    To set up the development environment and run the included demo application, use the following commands:

    1. Install dependencies: pnpm install
    2. Run the demo in watch mode: pnpm dev (this watches both FlexLayout and the Demo app)
    3. Run Playwright tests: pnpm playwright
    4. Build the npm distribution: pnpm build
    pnpm install
    pnpm dev
    pnpm playwright
    pnpm build
  3. Include a FlexLayout theme

    master

    FlexLayout requires a CSS theme to be imported. You can choose from several themes including alpha_light, alpha_dark, alpha_rounded, light, dark, underline, gray, rounded, or combined.

    Note: Using combined allows for dynamic theme switching via CSS classes.

    import 'flexlayout-react/style/alpha_light.css';  
  4. Dynamically change the theme

    master

    To switch themes dynamically, use the combined.css theme. Add a className to the div containing the <Layout> component in the format flexlayout__theme_[theme-name].

    Example:

    // Initial render with alpha_light
    <div className="flexlayout__theme_alpha_light">
        <Layout model={model} factory={factory} />
    </div>
    
    // Changing to alpha_dark in code
    containerRef.current.className = "flexlayout__theme_alpha_dark";
    <div ref={containerRef} className="flexlayout__theme_alpha_light">
        <Layout model={model} factory={factory} />
    </div>
    
    // Change the theme in code by changing the className on the containing div.
    containerRef.current!.className = "flexlayout__theme_alpha_dark"
  5. Configure Popout Windows

    master

    Tabs can be moved into external browser windows by enabling enablePopout and enablePopoutIcon in the tab attributes. This is useful for multi-monitor setups.

    Implementation Requirements

    1. Host Page: You must host an additional HTML page, popout.html, at the same location as your main application. This page acts as the container for the popped-out tab.
    2. Accessing Window/Document: Because popouts run in a different document context, standard global window or document calls may fail. To interact with the popout's environment, use a ref to an element inside the tab to retrieve the correct context:
    const currentDocument = selfRef.current.ownerDocument;
    const currentWindow = currentDocument.defaultView!;

    Security and Deployment

    • Same Origin: popout.html must be served from the same origin as the main page.
    • CSP (style-src): The main page's styles are injected into the popout. If using a strict style-src, ensure your CSS URLs are allowed. Note that inline <style> elements (e.g., from Emotion or styled-components) may be blocked because they cannot carry the main window's nonce. Prefer external CSS files.
    • COOP/COEP: If using Cross-Origin Isolation headers, popout.html must be served with compatible headers.
    • Popup Blockers: If window.open is blocked, FlexLayout gracefully degrades the popout to a floating panel within the main window.
  6. Import core FlexLayout components and models

    master

    The flexlayout package provides a complete set of view components and model abstractions for managing complex layouts.

    View Components:

    • Layout: The primary component for rendering the layout.
    • TabLayout: Component for managing tab-based views.
    • PopupMenu: Component for displaying context menus.

    Model Abstractions:

    • Model: The root object representing the entire layout state.
    • Node: The base class for all layout elements.
    • RowNode, TabSetNode, BorderNode, TabNode: Specific node types for structuring the layout.
    • Actions: Interface for performing operations on the model.
    • DockLocation, Orientation: Enums/types for positioning and layout direction.

    Types and Utilities:

    • LayoutTypes, Icons, I18nLabel, CSSClassNames: Supporting types and constants for styling and localization.
  7. Structure of the IJsonModel layout configuration

    master

    The IJsonModel interface defines the complete JSON schema used to serialize and deserialize a FlexLayout model. A layout is composed of a root layout (a row), optional borders for side/top/bottom tab strips, and optional subLayouts for nested or floating layouts.

    Key components:

    • layout: The top-level IJsonRowNode. Note that the top-level row is horizontal by default; rows nested within rows take the opposite orientation of their parent (e.g., a row inside a horizontal row acts as a column).
    • borders: An array of IJsonBorderNode defining tab strips at the top, bottom, left, or right edges.
    • subLayouts: A dictionary of IJsonSubLayout objects, used for popouts or nested layouts referenced by subLayoutId in a tab.
    • global: Optional IGlobalAttributes to set default behaviors for the entire layout.
  8. Create new tabs using the Layout API

    master

    If you are using React, you can access the ILayoutApi through a React ref to the Layout component. This allows you to programmatically add tabs to specific tabsets.

    Use layoutRef.current.addTabToTabSet(tabsetId, tabAttributes) to add a tab to a target tabset.

    layoutRef.current.addTabToTabSet("NAVIGATION", { type: "tab", component: "grid", name: "a grid" });
  9. Configure keyboard shortcuts via keyMap

    master

    FlexLayout provides built-in keyboard operability. You can customize command shortcuts by passing a keyMap object to the Layout component. Bindings are merged over the defaultKeyMap. To disable a specific shortcut, pass undefined for that key.

    Shortcut strings use KeyboardEvent.key names, optionally prefixed with modifiers like Ctrl, Shift, Alt, or Meta joined with + (e.g., "Ctrl+Delete").

    Note that structural ARIA widget patterns (like arrow keys for navigating tabs or splitters) are fixed and cannot be remapped.

    <Layout
        model={model}
        factory={factory}
        keyMap={{ focusTabToggle: "F6", focusNextTabset: "Ctrl+]", focusPreviousTabset: "Ctrl+[" }}
    />