New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

flexycakes

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flexycakes

Community fork of caplin/FlexLayout (ISC). Not affiliated.

latest
Source
npmnpm
Version
1.3.3
Version published
Maintainers
1
Created
Source
React Hook Form Logo - React hook custom hook for form validation

npm downloads npm Discord

Examples | API | Quick Start | Feature Tracker | Sandbox | Flexlayout

This is Flexycakes, a fork of FlexLayout with enhanced features including pin/unpin functionality for panels. Flexycakes extends the original FlexLayout capabilities with additional user interface improvements and workflow optimizations.

📍 Pin Board

💰 Paid Bounties Program

🚀 Exciting News! We're launching a paid bounty system to support young developers in the open source community.

Join Discord

What we're working on:

  • 🔍 Researching the best bounty platforms
  • 📋 Setting up contract logistics
  • 🎯 Defining contribution opportunities
  • 💡 Creating developer-friendly workflows

Stay tuned: Join our Discord community for real-time updates and early access to bounty opportunities!

🚀 Quick Start

Installation

Install Flexycakes from npm:

npm install flexycakes

or using yarn:

yarn add flexycakes

or using pnpm:

pnpm add flexycakes

Basic Setup

  • Import the components:

    import { Layout, Model } from "flexycakes";
    
  • Include a theme:

    Option A: Import in your JavaScript code:

    import "flexycakes/style/light.css";
    

    Option B: Link in your HTML:

    <link rel="stylesheet" href="/style/light.css" />
    
  • Optional: For dynamic theming, see Theme Switching

Development Setup with Symbolic Linking

If you're contributing to Flexycakes or want to develop locally:

  • Clone the repository:

    git clone https://github.com/powerdragonfire/flexycakes.git
    cd flexycakes
    
  • Install dependencies:

    pnpm install
    
  • Create a symbolic link:

    # Build the library first
    pnpm build
    
    # Create global link
    npm link
    # or with pnpm
    pnpm link --global
    
  • Link in your project:

    cd /path/to/your/project
    npm link flexycakes
    # or with pnpm
    pnpm link --global flexycakes
    
  • Start development mode:

    # In flexycakes directory
    pnpm dev
    

    This will watch for changes and rebuild automatically.

📖 Usage Guide

Basic Layout Setup

The <Layout> component renders the tabsets and splitters. Here's what you need:

Required Props

PropTypeDescription
modelModelThe layout model containing the structure
factoryFunctionCreates React components for each tab

💡 Tip: See Optional Layout Props for additional configuration options.

Core Concepts

The model is a tree of Node objects that define your layout structure:

  • Created using Model.fromJson(jsonObject)
  • Saved using model.toJson()

The factory function takes a Node object and returns the React component to render in that tab.

Simple Example

// Define your layout structure
const json = {
    global: {},
    borders: [],
    layout: {
        type: "row",
        weight: 100,
        children: [
            {
                type: "tabset",
                weight: 50,
                children: [
                    {
                        type: "tab",
                        name: "Dashboard",
                        component: "dashboard",
                    },
                ],
            },
            {
                type: "tabset",
                weight: 50,
                children: [
                    {
                        type: "tab",
                        name: "Settings",
                        component: "settings",
                    },
                ],
            },
        ],
    },
};

// Create your app
const model = Model.fromJson(json);

function App() {
    const factory = (node) => {
        const component = node.getComponent();

        switch (component) {
            case "dashboard":
                return <DashboardComponent />;
            case "settings":
                return <SettingsComponent />;
            default:
                return <div>{node.getName()}</div>;
        }
    };

    return <Layout model={model} factory={factory} />;
}
Simple layout

🎮 Try it live: CodeSandbox Demo | TypeScript Example

🏗️ Layout Structure

JSON Model Components

The model JSON has 4 main sections:

SectionRequiredDescription
globalGlobal layout options
layoutMain layout hierarchy
bordersEdge panels ("top", "bottom", "left", "right")
popoutsExternal window definitions

Node Types

🔹 Row Nodes

  • Purpose: Container for tabsets and child rows
  • Orientation: Top-level rows are horizontal (unless rootOrientationVertical is set)
  • Children: Tabsets and other rows

🔹 TabSet Nodes

  • Purpose: Container for tabs
  • Properties: List of tabs + selected tab index
  • Behavior: Auto-created when tabs move, deleted when empty (unless enableDeleteWhenEmpty: false)

🔹 Tab Nodes

  • Purpose: Individual panel content
  • Properties: Component name (for factory) + display text
  • Content: Loaded via the factory function

🔹 Border Nodes

  • Purpose: Edge-docked panels
  • Location: Can only exist in the borders section
  • Behavior: Similar to tabsets but docked to screen edges

FlexLayout Demo Showing Layout

💡 Pro Tip: Use the demo app to visually create layouts, then export the JSON via 'Show Layout JSON in console'.

Weight System

Node weights determine relative sizing:

  • Example: Weights of 30,70 = same as 3,7
  • Usage: Only relative values matter
  • Application: Applies to rows and tabsets within their parent

🎨 Customization

Theme Switching

Available Themes

  • light.css - Clean light theme
  • dark.css - Dark mode theme
  • gray.css - Neutral gray theme
  • underline.css - Minimal underline style
  • rounded.css - Rounded corners theme
  • combined.css - All themes in one file

Dynamic Theme Switching

Use the combined.css theme for runtime switching:

// Setup with theme container
<div ref={containerRef} className="flexlayout__theme_light">
    <Layout model={model} factory={factory} />
</div>;

// Change theme programmatically
containerRef.current.className = "flexlayout__theme_dark";

Custom Tab Rendering

Customize individual tabs with onRenderTab:

Tab customization areas
const onRenderTab = (node, renderValues) => {
    // renderValues.leading = <Icon />; (red area)
    // renderValues.content += " *"; (green area)
    renderValues.buttons.push(<MenuIcon key="menu" />); // yellow area
};

<Layout model={model} factory={factory} onRenderTab={onRenderTab} />;

Custom TabSet Rendering

Customize tabset headers with onRenderTabSet:

TabSet customization areas
const onRenderTabSet = (node, renderValues) => {
    // Add persistent buttons (red area)
    renderValues.stickyButtons.push(
        <button key="add" onClick={() => addNewTab(node)}>
            +
        </button>,
    );

    // Add contextual buttons (green area)
    renderValues.buttons.push(<SettingsIcon key="settings" />);
};

⚡ Actions & Events

Model Actions

All layout changes happen through actions via Model.doAction():

// Add a new tab
model.doAction(
    Actions.addNode(
        { type: "tab", component: "grid", name: "New Grid" },
        "targetTabsetId",
        DockLocation.CENTER,
        0, // position (use -1 for end)
    ),
);

// Update global settings
model.doAction(
    Actions.updateModelAttributes({
        splitterSize: 40,
    }),
);

📚 Reference: Full Actions API

Tab Events

Handle tab lifecycle events:

function MyComponent({ node }) {
    useEffect(() => {
        // Listen for resize events
        node.setEventListener("resize", ({ rect }) => {
            console.log("Tab resized:", rect);
        });

        // Save data before serialization
        node.setEventListener("save", () => {
            node.getConfig().myData = getCurrentData();
        });

        // Handle visibility changes
        node.setEventListener("visibility", ({ visible }) => {
            if (visible) startUpdates();
            else stopUpdates();
        });
    }, [node]);
}

Available Events

EventParametersDescription
resize{rect}Tab resized during layout
closenoneTab is being closed
visibility{visible}Tab visibility changed
savenoneBefore serialization to JSON

🪟 Popout Windows

Overview

Render tabs in external browser windows for multi-monitor setups.

Setup Requirements

  • HTML Host Page: Copy popout.html to your public directory
  • Tab Configuration: Add enablePopout: true to tab definitions
  • Styling: Styles are automatically copied from main window

Code Considerations

Popout windows use a different document and window. Access them via:

function PopoutComponent() {
    const selfRef = useRef();

    const handleEvent = () => {
        // ❌ Wrong - uses main window
        document.addEventListener("click", handler);

        // ✅ Correct - uses popout window
        const popoutDoc = selfRef.current.ownerDocument;
        const popoutWindow = popoutDoc.defaultView;
        popoutDoc.addEventListener("click", handler);
    };

    return <div ref={selfRef}>Content</div>;
}

Limitations

  • ⚠️ Context: Code runs in main window JS context
  • ⚠️ Events: Must use popout window/document for listeners
  • ⚠️ Throttling: Timers throttle when main window is hidden
  • ⚠️ Libraries: Third-party controls may not work without modification
  • ⚠️ Zoom: Incorrect sizing when browser is zoomed
  • ⚠️ State: Windows can't reload in maximized/minimized states

📖 Deep Dive: React Portals in Popups

🛠️ Development

Running Locally

# Install dependencies
pnpm install

# Start development server
pnpm dev

# Run tests (in separate terminal)
pnpm playwright
Playwright UI

Building

# Build for distribution
pnpm build

The built files will be in the dist/ directory.

📚 Appendix

🔧 Configuration Reference

Layout Properties

Complete list of optional props for the <Layout> component:

JSON Model Schemas

TypeScript interfaces for all configuration objects:

Core Model

Node Types

🎯 Advanced Usage

Layout Component Methods

Programmatically add tabs using Layout component methods:

// Get reference to Layout component
const layoutRef = useRef();

// Add tab to specific tabset
layoutRef.current.addTabToTabSet("NAVIGATION", {
    type: "tab",
    component: "grid",
    name: "New Grid",
});

Complete Layout Methods API

Multi-Splitter Mode

Remove tabs entirely for a pure splitter interface:

const json = {
    global: {
        tabSetEnableTabStrip: false,
    },
    // ... rest of layout
};

Node ID Management

// Auto-generated IDs are UUIDs
const autoId = "#0c459064-8dee-444e-8636-eb9ab910fb27";

// Get node ID
const nodeId = node.getId();

// Use in actions
model.doAction(Actions.selectTab(nodeId));
🔗 Alternative Solutions

Comparing Flexycakes with other React layout managers:

LibraryRepositoryKey Features
Flexycakespowerdragonfire/flexycakesEnhanced FlexLayout with pin/unpin
rc-dockticlo/rc-dockDock-style layouts
Dockviewdockview.devModern docking solution
Luminojupyterlab/luminoJupyterLab's layout system
Golden Layoutgolden-layout/golden-layoutMulti-window layouts
React Mosaicnomcopter/react-mosaicTiling window manager
📋 Migration Guide

From FlexLayout to Flexycakes

Flexycakes is a drop-in replacement for FlexLayout with additional features:

  • Update package:

    npm uninstall flexlayout-react
    npm install flexycakes
    
  • Update imports:

    // Before
    import FlexLayout from "flexlayout-react";
    
    // After
    import { Layout, Model } from "flexycakes";
    
  • Update CSS imports:

    // Before
    import "flexlayout-react/style/light.css";
    
    // After
    import "flexycakes/style/light.css";
    

New Features in Flexycakes

  • 📌 Pin/Unpin functionality for panels
  • 🎨 Enhanced UI components
  • ⚡ Improved workflow optimizations
  • 🔧 Additional customization options

Keywords

react

FAQs

Package last updated on 01 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts