A multi window layout manager for webapps

Overview

Golden Layout

NPM version License

Version 2

Version 2.0 is now available from NPM.

This version is a substantial change from the previous (1.5.9) version. The change can be summarised as:

  1. The code has been ported to TypeScript
  2. The primary focus of maintenance will be on reliability.

Before migrating from version 1, it is important to review the following:

Dropped Features

As part of the port, the code base was significantly refactored. A number of features have been dropped from the version 1.0 as their implementation was not robust enough to meet the reliability requirements of version 2. The dropped features are:

  • React Support - The FlexLayout library has been designed for React components. We recommend developers using React to use this library instead of Golden Layout.
  • Nested Stacks - While it was possible to create layouts with Nested Stacks in version 1, the implementation was incomplete. Due to the large amount of work that would have been necessary to fix the implementation, it was decided instead to drop this feature. Version 2 explicitly does not allow nested stacks.
  • Internal and Public API - All classes, interfaces, functions and properties are marked as either internal or public. Only public APIs are generally available to applications.
  • Legacy Browsers - The library will now only target modern browsers (see package.json for browserlist configuration)
  • No JQuery - JQuery is no longer used in Golden Layout (many would consider this as an added feature)

Features implemented but not ready for production

Some features have been ported to TypeScript but are not yet ready for production. These features are:

  • Popouts - The coding for this has been completed however testing still needs to be carried out.
  • Touch Support - Improvements are required in accessing browser Touch/Drag APIs. Also some conceptual aspects of the implementation need to be improved. These will be carried out in a future release.
  • Some API functions - While most API functions have been ported, not all have been tested. The APIs used in the Test Application (both apitest app and Angular example) have been tested and are ready for production. Other API functions should work but please take this warning into account.

Migration

The Version 1 to Version 2 migration guide is available here.

Examples

Version 2 examples are presented here.

Features

  • Full touch support
  • Native popup windows
  • Completely themeable
  • Comprehensive API
  • Powerful persistence
  • Works in modern browsers (Firefox, Chrome)
  • Reponsive design

Installation / Usage

Library

Golden Layout is shipped via NPM. Use the following commands to install it into an application package:
npm i golden-layout

Source

The source can be installed by cloning the repository at:
https://github.com/golden-layout/golden-layout

To build the distribution locally, open a shell at the golden-layout directory/folder and run the following commands:

  1. npm install or npm ci (recommended) to install required dependencies
  2. npm run build to generate the distribution (dist subfolder). This script will:
    • delete the existing lib and dist folders
    • compile the TypeScript code
    • generate the rolled up TypeScript definition files (index.d.ts and golden-layout-untrimmed.d.ts)
    • generate source map
    • copy the style files to the dist folder

Note that the lib subfolder only holds the TypeScript declaration files generated by the compiler. Generally this subfolder can be ignored. It is used during the build process to generate the rolled up TypeScript definition files.

Build and run demo/test app

After installing the source and building the distribution, you can build and start the apitest (demo) app to view the library in action. Use the following commands:

  • npm run apitest:build to just build it
  • npm run apitest:serve to both build and start the development server.
    You can then view it in your browser using the following link:
    http://localhost:3000/

Debugging Golden Layout library

The apitest app can be used to debug the Golden Layout library. Its webpack configuration will import the Golden Layout library source map, allowing debuggers to step through the library source code and place break points.

If you wish to test the library with other applications, you can link to the Golden Layout repository without having to install it into the application from NPM. This is done with the npm link command. Use the following steps:

  1. Make sure that the golden-layout package is not included as a dependency in the application's package
  2. Run the npm link from a shell in the golden-layout source repository top level folder.
  3. Run npm link golden-layout from a shell in your application's top level folder.

Your application will then use the distribution in the Golden Layout repository dist subfolder. If you wish to make changes to the Golden Layout library, you will need to run the build:api to regenerate the dist folder.

Angular Example App

A sample Angular application using Golden Layout is available. More details are here.

Migration

Version 2 has been re-written in TypeScript. A general code cleanup has been carried out as part of this re-write.

Also, some changes have been made to the GoldenLayout API. Where possible, backwards compatibility has been retained,however functions and properties kept for backwards compatibility have been marked as deprecated. It is strongly recommend applications be migrated to the new API.

The API changes include 2 new events to support creation of components: getComponentEvent and releaseComponentEvent. With these events, it is far easier to integrate GoldenLayout into frameworks. This example application demonstrates how to integrate GoldenLayout into Angular: https://github.com/golden-layout/golden-layout-ng-app

Config

Configs are now strongly typed. In addition, GoldenLayout now has "Configs" and "Resolved Configs"

  1. Configs
    Application developers will mainly work with "Configs". A "Config" supports optional properties. If a property is not specified, a default will be used. In addition, "Config" also will handle backwards compatibility. It will migrate deprecated properties to their new values.
    Config parameters in GoldenLayout API methods will be of type "Config". The one exception is LayoutConfig.saveLayout() which returns a "Resolved Config".
  2. Resolved Configs
    Golden-Layout internally uses "Resolved Config"s. Whenever an API function is passed a "Config", GoldenLayout will resolve it to its corresponding "Resolved Config". This resolving process will set default values where an optional value has not been specified. It will also handle backwards compatibility. This allows the GoldenLayout library to always work with fully configured Configs.

For persistence of configs, always save the "Resolved Config" returned by LayoutManager.saveLayout(). When reloading a saved Layout, first convert the saved "Resolved Config" to a "Config" by calling LayoutConfig.fromResolved().

Both "Resolved Config" and "Config" have 2 types of interface hierarchies:

  1. ItemConfig
    This specifies the config for a content item.
  2. LayoutConfig (previously the Config interface)
    This specifies the config for a layout.

The (optional) ItemConfig.id property now has type string (instead of its previous string | string[] type). For backwards compatibility, when ItemConfig.id is resolved, it will still accept an id with of type string array. This will allow handling of legacy saved configs in which id contains an array of strings (including possibly the legacy maximise indicator). When such an id is resolved, the array is first checked for the legacy maximise indicator and then the first element becomes the id string value. The remaining elements are discarded.

The ComponentItemConfig.componentName property has now been replaced by property ComponentItemConfig.componentType. componentType is of type JsonValue. While a component type can now be specified by values that can be serialised by JSON, componentType must be of type string if it is registered with one of the following functions:

  1. LayoutManager.registerComponent() (deprecated)
  2. LayoutManager.registerComponentConstructor()
  3. LayoutManager.registerComponentFactoryFunction()

A LayoutConfig has a root property which specifies the ItemConfig of root content item of the layout. root is not optional and must always be specified.

The LayoutConfig selectionEnabled property has been removed. Clicking of Stack Headers can now be handled with the new stackHeaderClick event (which is always enabled).

ResolvedLayoutConfig now has functions to minify and unminify configurations:

  1. minifyConfig() Replaces LayoutManager.minifyConfig()
  2. unminifyConfig() Replaces LayoutManager.unminifyConfig()

For examples of how to create LayoutConfigs, please refer to the apitest program in the repository.

Many of the Config properties have been deprecated as they overlapped or were moved to more appropriate locations. Please refer to the config.ts source file for more information about these deprecations.

GoldenLayout class

GoldenLayout is now a distinct class which is a descendant of the LayoutManager class. Your application should always create an instance of this class.

The GoldenLayout constructor takes one optional parameter: the HTML element which contains the GoldenLayout instance. If this is not specified, GoldenLayout will be placed under body.

Note that the initial Layout is no longer specified in this constructor. Instead it is loaded with LayoutManage.loadLayout() (see below).

LayoutManager changes

  1. Do not construct an instance of LayoutManager. Construct an instance of GoldenLayout (see above).
  2. registerComponentConstructor() (new function)
    Same as previous registerComponent() however only used when registering a component constructor.
  3. registerComponentFactoryFunction (new function)
    Same as previous registerComponent() however only used when registering a call back function (closure) for creating components.
  4. Do not use registerComponent(). Use the new registerComponentConstructor() or registerComponentFactoryFunction() instead.
  5. getComponentEvent (new event)
    Generate a component needed by GoldenLayout. The parameters specify its container and ItemConfig. Use this event instead of registerComponentConstructor() or registerComponentFactoryFunction if you want to control the disposal of the component.
  6. releaseComponentEvent (new event)
    Use in conjunction with getComponentEvent to release/dispose any component created for GoldenLayout
  7. Do not call init(). Call LayoutManager.loadLayout() instead.
  8. loadLayout() (new function)
    Will load the new layout specified in its LayoutConfig parameter. This can also be subsequently called whenever the GoldenLayout layout is to be replaced.
  9. saveLayout() (new function)
    Saves the current layout as a LayoutConfig. Replaces the existing toConfig() function.
  10. Do not uses minifyConfig() of unminifyConfig() functions. Use the respective functions in ResolvedLayoutConfig.
  11. Do not call toConfig(). Call LayoutManager.saveLayout() instead.
  12. setSize() (new function)
    Sets the size of the GoldenLayout instance in pixels. Replaces the existing updateSize() function.
  13. Do not use updateSize(). Use the new LayoutManager.setSize() instead.
  14. rootItem (new property) Specifies the root content item of the layout (not the Ground content item).
  15. Do not use root. This has been replaced with the internal property groundItem. You probably want to use the new rootItem instead.
  16. focusComponent() will focus the specified component item. Only one component item can have focus. If previously, another component item had focus, then it will lose focus (become blurred). focus or blur events will be emitted as appropriate unless the suppressEvent parameter is set to true.
  17. clearComponentFocus() which removes any existing component item focus. If focus is removed, a blur event will be emitted unless the suppressEvent parameter is set to true.

Content Items

  1. AbstractContentItem has been renamed to ContentItem
  2. config property has been removed. Use the toConfig() method instead (as recommended in the original GoldenLayout documentation).
  3. Some of the previous config properties such as id and type are now available as properties of ContentItem or its descendants (where appropriate).
  4. id now has type string. (It used to be string | string[].)
  5. ItemContainer has been renamed to ComponentContainer
  6. Component has been renamed to ComponentItem. "Component" now refers to the external component hosted inside GoldenLayout
  7. Root has been renamed to GroundItem and has been marked as internal only. Applications should never access GroundItem. Note that the layout's root ContentItem is GroundItem's only child. You can access this root ContentItem with LayoutManager.rootItem.
  8. Stack.getActiveContentItem() and Stack.setActiveContentItem() have been renamed to respective Stack.getActiveComponentItem() and Stack.setActiveComponentItem()
  9. ContentItem.select() and ContentItem.deselect() have been removed. Use the new ComponentItem.focus() and ComponentItem.blur() instead.
  10. ComponentItem.focus() (new function) will focus the specified ComponentItem. It will also remove focus from another component item which previously had focus. Only one component item can have focus at any time. If layout focus has changed, a focus event will be emitted (unless suppressEvent parameter is set to true).
  11. ComponentItem.blur() (new function) will remove focus from the specified ComponentItem. After this is called, no component item in the layout will have focus. If the component lost focus, a blur event will be emitted (unless suppressEvent parameter is set to true).

ComponentContainer

  1. element (new property - replaces getElement())
    Returns HTMLElement which hosts component
  2. Do not use getElement(). Use the new element property instead
  3. initialState (new getter)
    Gets the componentState of the ComponentItemConfig used to create the contained component.
  4. stateRequestEvent (new event)
    If set, stateRequestEvent is fired whenever GoldenLayout wants the latest state for a component. Calling LayoutManager.saveLayout() will cause this event to be fired (if it is defined). If it is not defined, then the initial state in the ItemConfig or the latest state set in setState() will be saved.
  5. beforeComponentRelease (new EventEmitter event)
    beforeComponentRelease is emitted on the container before a component is released. Components can use this event to dispose of resources.
  6. Do not use getState() unless you are using the deprecated setState(). Use ComponentContainer.initialState getter if you have migrated to the new ComponentContainer.stateRequestEvent.
  7. setState() has been marked as deprecated. If possible, use the new stateRequestEvent event instead.
  8. replaceComponent() allows you to replace a component in a container without otherwise affecting the layout.

Header and Tab

Several properties and functions have been renamed in header.ts and tab.ts. Please search for "@deprecated" in these files for these changes.

Events

  1. All DOM events are now propagated so that they can be handled by parents or globally.
  2. preventDefault() is only called by MouseMove listener used in DragListener. All other event listeners are added with passive: true.
  3. Bubbling Events are now emitted with the parameter EventEmitter.BubblingEvent (or descendant)
  4. New EventEmitter events:
    • beforeComponentRelease
    • stackHeaderClick - Bubbling event. Fired when stack header is clicked - but not tab.
    • stackHeaderTouchStart - Bubbling event. Fired when stack header is touched - but not tab.
    • focus - Bubbling event. Fired when a component gets focus.
    • blur - Bubbling event. Fired when a component loses focus.

Other

  1. undefined is used instead of null for new properties, events etc. Some internals have also been switched to use undefined instead of null. Existing properties using null mostly have been left as is however it is possible that some of these internal changes have affected external properties/events/methods.

Deprecations

For most changes, the existing functions and properties have been left in place but marked as deprecated. It is strongly recommended that applications be reworked not to use these deprecations. Bugs associated with deprecations will be given low priority (or not fixed at all). Also, deprecated aliases, methods and properties may be removed in future releases.

Public and Internal APIs

All API elements (classes, interfaces, functions etc) have been labelled as either public or internal. Applications should only use public API elements. Internal API elements are subject to change and no consideration will be given to backwards compatibility when these are changed.

The library distribution includes 2 TypeScript declaration (typing) files:

  1. index.d.ts which contains only public API elements. Applications should use this declaration file to access the library.
  2. golden-layout-untrimmed.d.ts which contains all (public and internal) API elements. Use this declaration file if you wish to access any API element in the library however please take the above warning into account.

Note that the allocation of API elements to either public or internal has not been finalised. However any element used in either the apitest application or the example Angular application will remain labelled as public.

Code Examples

Angular

An example Angular application using Golden Layout is available. The source can be installed by cloning the repository:
https://github.com/golden-layout/golden-layout-ng-app

After installing the source, the app can be built and started with the standard build and start scripts.

Vue

The following snippets of code demonstrate how Golden Layout can be used in Vue.

Composable Hook

import { GoldenLayout, LayoutConfig, LayoutManager } from 'golden-layout';
import { Component, createVNode, onMounted, ref, render } from 'vue';

export const isClient = typeof window !== 'undefined';
export const isDocumentReady = () => isClient && document.readyState === 'complete' && document.body != null;

export function useDocumentReady(func: () => void) {
    onMounted(() => {
        console.log(isDocumentReady());
        if (isDocumentReady()) func();
        else
            document.addEventListener('readystatechange', () => isDocumentReady() && func(), {
                passive: true,
            });
    });
}

export function useGoldenLayout(components: Record<string, Component>, config?: LayoutConfig) {
    const element = ref<HTMLElement | null>(null);
    const layout = ref<GoldenLayout | null>(null);
    const initialized = ref(false);

    const componentsTypeMap = new Map<string, Component>(Object.entries(components));

    useDocumentReady(() => {
        if (element.value == null) throw new Error('Element must be set.');
        const goldenLayout = new GoldenLayout(element.value);

        const getComponentEvent: LayoutManager.GetComponentEventHandler = (container, itemConfig) => {
            const { componentType } = itemConfig;
            if (typeof componentType !== 'string') throw new Error('Invalid component type.');

            const component = componentsTypeMap.get(componentType);
            if (component == null) throw new Error(`Component not found: '${componentType}'`);

            const node = createVNode(component);
            render(node, container.element);
        };
        goldenLayout.getComponentEvent = getComponentEvent;

        if (config != null) goldenLayout.loadLayout(config);

        // https://github.com/microsoft/TypeScript/issues/34933
        layout.value = goldenLayout as any;

        initialized.value = true;
    });

    return { element, initialized, layout };
}

Usage

const Test = defineComponent(() => <span>It Works!</span>);

export const Layout = defineComponent(() => {
    const { element } = useGoldenLayout(
        { Test },
        {
            root: {
                type: 'row',
                content: [
                    {
                        type: 'component',
                        componentType: 'Test',
                    },
                ],
            },
        }
    );
    return () => <div ref={element} style="width: 100%; height: 75vh"></div>;
});

Other Frameworks

When attaching a component, all Golden Layout does is provide the HTML Element of a container: Container.element. Components can use this element to bind to that Golden Layout container. For example, the component's top most HTML element could be attached as a child to this container element.

The LayoutManager.getComponentEvent event will be fired whenever a container is created and needs a component. The LayoutManager.releaseComponentEvent event will be fired before a container is destroyed and gives the application a chance to tear-down the component.

These events can be set up in an application's start up code as shown in the example code below.

    this._goldenLayout = new GoldenLayout(goldenLayoutHostElement);

    this._goldenLayout.getComponentEvent = (container, itemConfig) => {
        const component = this.createFrameworkComponent(itemConfig);
        // component.element is the top most HTML element in the component
        container.element.appendChild(component.element);
        this._containerMap.set(container, component);
    }

    this._goldenLayout.releaseComponentEvent = (container, component) => {
        // do this if you need to dispose resources
        const component = this._containerMap.get(container);
        this.disposeFrameworkComponent(component);
        this._containerMap.delete(container);
    }

Alternatively, container.element could be used as the top most HTML element in the component. Example code for this could look like:

    this._goldenLayout = new GoldenLayout(goldenLayoutHostElement);

    this._goldenLayout.getComponentEvent = (container, itemConfig) => {
        const component = this.createFrameworkComponent(itemConfig, container.element);
        this._containerMap.set(container, component);
    }

    this._goldenLayout.releaseComponentEvent = (container, component) => {
        // do this if you need to dispose resources
        const component = this._containerMap.get(container);
        this.disposeFrameworkComponent(component);
        this._containerMap.delete(container);
    }

Once the LayoutManager.getComponentEvent and (optionally) LayoutManager.releaseComponentEvent events have been set up, functions that create components can be used. For example:

  • LayoutManager.loadLayout()
  • LayoutManager.addComponent()

Also note that if LayoutManager.getComponentEvent is set up, you should not register any components with the register functions:

  • LayoutManager.registerComponent()
  • LayoutManager.registerComponentConstructor()
  • LayoutManager.registerComponentFactoryFunction()
  • LayoutManager.registerComponentFunction()
  • LayoutManager.registerGetComponentConstructorCallback()

LayoutManager.getComponentEvent is the recommended approach for binding components to Golden Layout. The above component register functions, were mainly included in Golden Layout for backwards compatibility.

Comments
  • Is this package still maintained? Looking for new maintainers?

    Is this package still maintained? Looking for new maintainers?

    Hi @WolframHempel !

    I'm opening this issue to thank you for your work, and offer support. I'd like to use this package, but there are a few issues I'd need to fix, and would LOVE to fix them (together with anyone who'd want to). Would you consider moving this Repo into an organisation on github, and giving control to the list of people who have been filing good issue-reports and pull-requests?

    I'm not directly asking for myself, though I'd love to be involved, I can clearly see some people who have stepped forwards already multiple times to take this package back into support:

    @malled @Slowki @ntamas @soh1988 @jfmmm @pmunin

    There are probably more people that deserve to be on that list (if you're reading this and know them, why not tag them in this thread?).

    Do you think we could have a chat about this someday soonish? Hope to hear from you

    Norbert

    Help Wanted Documentation 
    opened by ndelangen 86
  • docker was my goal :)

    docker was my goal :)

    hi @mattgodbolt this PR is draft and it needs consideration for icon images and overall design for all themes what about design - my hands grows from fifth point :)

    demo https://akajes.github.io/golden-layout/

    opened by akaJes 47
  • Virtual Components

    Virtual Components

    Introduction

    This issue is in response to #662 and #470 both raised by @PerBothner. In these PRs, @PerBothner presents the idea of having a Golden Layout component (ie the component provided by the application that is visually displayed in a layout) not be a child element within the Golden Layout DOM. As per #470: “The advantage is that the content element is not moved around in the DOM, which avoids breaking iframe, sockets, etc.”

    The purpose of this issue is to present an initial approach for implementing this feature and refining it.

    I have called this feature “Virtual Components”. It is analogous to virtual grids where the string values shown in cells are not actually stored in the grid. Instead, the grid uses events to access the strings whenever they are required.

    Below are my thoughts on how Virtual Components could be implemented:

    LayoutManager.GetComponentEvent change

    This event’s handler’s signature is modified so that it can also return undefined. If the handler returns undefined, the component is virtual. The application should create (or assign) the component and associate it with the container but:

    • not make it a child the container’s element, and
    • not return it

    The handler will also need to set up some events on the container. This is discussed below.

    LayoutManager.ReleaseComponentEvent not changed

    This event’s handler’s signature is not modified and remains optional. Its use remains the same - applications can perform some processing whenever a component is deleted from the layout.

    new ComponentContainer Events

    Golden Layout sets the position, size and visibility of components. Currently it does this by assuming the component is a child element of the ComponentContainer’s element and managing the ComponentContainer’s element.

    The ComponentContainer’s element has position type static so its left, top values are ignored and it is positioned by the browser. The element’s size and width are explicitly set by GoldenLayout code (ContentItem.updateSize() and related functions). The element’s visibility is also explicitly set by GoldenLayout code (ContentItem.show() and ContentItem.hide()).

    If a component is virtual, then it is not a child of ComponentContainer.element and the above will not work. Instead, the application will need to position the component and change its visibility. Containers will have the following new events which the application can use to manage a component’s position, size and visibility:

    • ComponentContainer.visiblityChangedEvent: (this: void, visible: boolean) => void;
    • ComponentContainer.positionChangedEvent: (this: void, x: number ???, y: number ???) => void;
    • ComponentContainer.sizeChangedEvent: (this: void, width: number, height: number) => void;
    • ComponentContainer.positionOrSizeChangedEvent: (this: void, x: number ???, y: number ???, width: number, height: number) => void;

    The last event (positionOrSizeChangedEvent) is there for convenience. Applications could use this instead of the separate position and size events. It may turn out that this should not be included depending on the integration with the rest of the Golden Layout code. (Alternatively, this should be kept, and the separate position and size events should not be included.)

    The application should assign handlers to these events when it handles the LayoutManager.GetComponentEvent.

    Position

    Integrating the ComponentContainer visibility and size events should be reasonably straight forward. However, the position event will need further investigation. This is because x and y are not calculated when updateSize() is called. Since ComponentContainer is static its position is relative to its parent ComponentItem and x and y are not relevant. The application however will need the position relevant to Golden Layout’s host element. Two possible approaches I can think of are:

    1. updateSize() is enhanced to calculate left and top of ComponentContainers relative to Golden Layout’s host element and pass these as x and y. This could be difficult if reflows affect previously calculated top and left values. Also, it would need to consider users possibly having modified elements such as the Stack Header’s element.
    2. Not pass x and y at all. The application can use getBoundingClientRect() to get the container’s element’s position in the document. It can then compare these against the Golden Layout’s host element’s position in the document (also obtained with getBoundingClientRect()). It can then position a component by making the host element ‘positioned’ (ie position !== static) and ensuring the component’s element’s position property is absolute. Golden Layout will ensure that ComponentContainer’s element and its parent elements have position value static.

    Some experimentation will probably be required to work out the best approach.

    LayoutManger update size events

    A few events should be added to LayoutManager to allow it to better manage the sizing of the components.

    1. beforeUpdateSizeEvent: (this: void) => void
      Gives an application a chance to carry out processing before update sizing begins.
    2. beforeVirtualSizingEvent: (this: void) => void
      This event should only be fired if virtual components are included in the layout. It gives the application a chance to calculate Golden Layout’s host element’s position in the document, with getBoundingClientRect(), prior to all the ComponentContainer’s firing their events. This way the host element’s position only has to be calculated once.
    3. afterUpdateSizeEvent: (this: void) => void
      Gives an application a chance to carry out processing after update sizing has been completed.

    Update Sizing order of processing

    Whenever sizing needs to be updated, the actions relevant to virtual components should occur in the following order:

    1. beforeUpdateSizeEvent is always fired
    2. the current updateSize processing is carried out on the layout so that all content items are positioned. However, it does not fire ComponentContainer virtual component events.
    3. If there are any virtual components, then the beforeVirtualSizingEvent is fired.
    4. For all virtual components, the relevant container events are fired.
    5. afterUpdateSizeEvent is always fired

    By positioning all the containers before firing any virtual component events, it avoids problems arising from reflows during the initial sizing process.

    Other tasks

    apitest

    The apitest program should be enhanced to support virtual components so this feature can be tested. Maybe include a drop down specifying how components are obtained:

    • Registered (what it currently does)
    • As required (obtained via LayoutManager.GetComponentEvent but included in DOM)
    • Virtual

    Whatever the approach, the key thing is that apitest can be used to test virtual components.

    Documentation

    A note should be included in README describing Virtual Components and how events should be used by applications if they want to use Virtual Components.

    Summary

    The above are my thoughts on how virtual components can be implemented. I am sure there will be things that I have missed.

    I do not have the time to implement virtual components (and have no need of them myself). However, I will be happy to review a PR generally in line with the above (or the outcomes of the discussion in this issue) for inclusion into the Golden Layout code base.

    opened by pbklink 35
  • TypeScript port: Golden Layout version 2 or new product?

    TypeScript port: Golden Layout version 2 or new product?

    The port mentioned in issue #591 is now complete (to the extent required by my company). I now need to publish this product to NPM to give others access to it.

    Am considering whether to publish as Golden Layout version 2 or a new product. The main driver behind this decision is ensuring this code base's ongoing reliability.

    I have outlined my thoughts in the readme at the TypeScript port repository https://github.com/pbklink/golden-layout. The main point being the vision on how the code base is maintained/enhanced to ensure its reliability.

    What do people think about the Golden Layout community adopting a policy based around this vision?

    opened by pbklink 25
  • Add React/ReactDOM as peer dependencies for node package

    Add React/ReactDOM as peer dependencies for node package

    Current behavior In my App.jsx file, I call import GoldenLayout from 'golden-layout'; This compiles just fine, but I get the following runtime error:

    Uncaught ReferenceError: ReactDOM is not defined
        at lm.utils.ReactComponentHandler._render (goldenlayout.js:4763)
        at lm.container.ItemContainer.emit (goldenlayout.js:257)
        at lm.items.Component._$init (goldenlayout.js:3408)
        at lm.items.Component.callDownwards (goldenlayout.js:2818)
        at lm.items.Stack.callDownwards (goldenlayout.js:2821)
        at lm.items.RowOrColumn.callDownwards (goldenlayout.js:2821)
        at lm.items.Root.callDownwards (goldenlayout.js:2821)
        at lm.LayoutManager._create (goldenlayout.js:1370)
        at lm.LayoutManager.init (goldenlayout.js:715)
        at mightThrow (jquery.js:3583)
    

    For this reason I'm guessing they're being referenced as UMD globals instead of being required by the golden-layout package.

    Expected behavior: calling import for GoldenLayout would properly resolve React and ReactDOM.

    Codepen example: Codepen doesn't support npm afaik

    App.jsx.txt

    React 
    opened by andrewcapodieci 25
  • Ability to Float a Pane and have it undocked over others in background

    Ability to Float a Pane and have it undocked over others in background

    Hi, I would like that could be possible to have also floating panes. Actually panes are docked or moved to another browser window but could be very useful to have also a third mode, "float" with pane that is placed in the same browser window but undocked (and freely draggable) and placed over others in background.

    Duplicate 
    opened by ldetomi 25
  • Embedding via events

    Embedding via events

    image

    Hello

    I am looking for information about how to implement the simplest example using embedding via events method from A to Z. I was looking for docs but anything on the website is for v1.5, I also wasn't able to find anything here in the issues or in the example projects. I don't know Vue or Angular, was working in React but that was a few years ago, I am working in Svelte now so my another question is - can it work with Svelte? (bundler in Svelte is Vite)

    I already know it won't work when I add it as a dependency from the NPM, so I did clone the repo and compiled the code to a bundle and imported it directly.

    There's few concepts not explained in the readme, I would be very grateful for the help: What is the implementation of this.createFrameworkComponent(itemConfig) function? What do I create and what are the possible properties of itemConfig? What is the component? Is that any content I put in the layout window? (I am asking because I think I saw somewhere that my custom component needs to inherit from the GL component class)

    How do I cause bindComponentEvent to fire and create the content inside GL window/tab?

    Why in this snippet the returned value contains virtual: false but later on there are mentions of VirtualLayout.bindComponentEvent and VirtualLayout.unbindComponentEvent? Are those separate, unrelated concepts?

    How do I create and/or reference the LayoutManager object that is mentioned multiple times in the readme?

    tl;dr how to make it work, simplest example without all the complexity of vue or angular, hooks etc, just create layout with 1 row and 2 columns split in 2, for example, and add some stuff inside 🙏

    opened by ljaniszewski 23
  • Usage with @connect breaks in various ways.

    Usage with @connect breaks in various ways.

    Rendering any React components that use react-redux and the HOC @connect causes golden-layout to fail to render with an error along the lines of: "Uncaught Invariant Violation: Could not find "store" in either the context or props of "Connect(DropdownMenu)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(DropdownMenu)".

    Our extremely kludgy "fix" is to manually copy the store across to context like so:

       static contextTypes : React.ValidationMap<any> = {
            store: React.PropTypes.shape({
                subscribe: React.PropTypes.func.isRequired,
                dispatch: React.PropTypes.func.isRequired,
                getState: React.PropTypes.func.isRequired
            })
        }
    
        content.props = {store: (this.context as any).store};
    

    and then later in our component to be rendered:

       static childContextTypes : React.ValidationMap<any> = {
            store: React.PropTypes.shape({
                subscribe: React.PropTypes.func.isRequired,
                dispatch: React.PropTypes.func.isRequired,
                getState: React.PropTypes.func.isRequired
            })
        }
    
        getChildContext() {
            return {store: this.props.store}
        }
    

    While this solves the nominal case, as soon as I try to pop out a component, I am back in a world without my store:

    :8060/dist/vendor.js:3324 Warning: Failed Context Types: Required child context `store.subscribe` was not specified in `TestItem`.warning @ :8060/dist/vendor.js:3324
    :8060/dist/vendor.js:3324 Warning: Failed Context Types: Required context `store.subscribe` was not specified in `Connect(DropdownMenu)`. Check the render method of `QueryViewToolbar`.warning @ :8060/dist/vendor.js:3324
    :8060/dist/vendor.js:37303 Uncaught TypeError: _this.store.getState is not a function
    

    Halp!

    React 
    opened by noah79 22
  • header position and stack/component personal header configuration

    header position and stack/component personal header configuration

    You can customize header in each stack or component

    • show: disable or change side of header position
    • frozen: prevent to be dragged and others dropped inside

    when type is 'stack' or 'component', if property omitted will be used default option

    header : {
        show: false | 'top' | 'left' | 'right' | 'bottom'
        maximize : false | 'custom label',
        minimize :  'custom label',
        popout :  false | 'custom label',
        close: 'custom label',
        frozen: false | true,
    }
    

    You can remove/disable splitters when type is 'row' or 'column'

    splitters: [ false, true ],
    

    TODO:

    • [x] dropdown menu position
    • [x] customized header configuration for each stack
    • [x] copy configuration to new created stacks
    • [x] align code
    • [x] row/column splitters config
    • [x] frozen for dragging
    • [x] invert bottom shadow css
    • [x] correct header position on preview, while dragging
    • [x] programmatic header position
    • [x] optimization
    • [x] correcting styles for themes
    • [x] build dist

    fast install for preview test

    git clone https://github.com/akaJes/golden-layout.git --branch sided_headers
    ln -s golden-layout /var/www/sided_headers
    xdg-open http://localhost/sided_headers
    
    opened by akaJes 20
  • Column removed after close a children

    Column removed after close a children

    Hi, having a layout like this:

    {
      content: [{
        type: 'row',
        content: [{
          type: 'column',
          content: [{
            type: 'component',
            componentName: 'first-component'
          }, {
              type: 'component',
              componentName: 'second-component'
            }]
          },{
            type: 'column',
            id: 'sec-col',
            content: [{
               type: 'component',
               componentName: 'third-component'
            }]
          }]
        }]
    }
    

    Current behavior

    In my project, I add a new component as child in second column (bellow third-component) using id, after I close the new added component, the column sec-col get removed, and the component third-component get added to root row.

    Expected behavior:

    Column should stay as it already still has a child third-component.

    Question More information needed 
    opened by Abdullah0991 19
  • npm package and typescript definitions out of date?

    npm package and typescript definitions out of date?

    Hi,

    I noticed that the npm package has last been updated in 2017. (https://www.npmjs.com/package/golden-layout)

    Since then several updates have been made to golden-layout according to the list of commits. Shouldn't the changes be made available over npm too?

    Additionally I noticed that the typescript definitions in index.d.ts do not reflect the current state of the project. For example: according to index.d.ts there is no such field as 'reorderEnabled' on item level although it can be used. When calling GoldenLayout.toConfig 'reorderEnabled' is present on item level. This also applies to the documentation (http://golden-layout.com/docs/ItemConfig.html) where there is no mention of 'reorderEnabled' in ItemConfig.

    Are there any plans to update this?


    Edit: I have seen that the latest release matches the one on npm. But it is also from 2017. When is the next release planned?

    opened by ConnorVD 19
  • How to disable dragging through code settings instead of initializing settings

    How to disable dragging through code settings instead of initializing settings

    How to disable dragging through code settings instead of initializing settings. When I run, it doesn't work to set it through the figure below, whether there are other API settings: image

    opened by Vision-Zhang 0
  • Limit max width/height of component?

    Limit max width/height of component?

    Hi, I'm trying to figure out a way to configure a max size for a component, so when the splitter is dragged, the component will not grow past the size. Being able to specify a max value for width or height would be perfect.

    I'm using the Embedding-Via-Registration method a layout config. So far I haven't found anything to control max width or height through the layout config, or the layout main object API.

    minsize or minwidth work though they seem to add up to a total width for the stack - as in if I have 2 tabs in a stack with minwidth: 100 each then the stacks total minwidth becomes 200. Is that expected?.

    Really hoping there's a solution. Much appreciated!

    opened by achamas-playco 0
  • Cancel drag with Escape?

    Cancel drag with Escape?

    Current behavior I noticed that once a drag is started, it can't be stopped by pressing the Escape key.

    Expected behavior: Would it be good to have the Escape key abort or cancel the drag, returning the item to its initial spot? I noticed there weren't any issues about this yet so I thought I'd start the conversation. Would this be easy to implement?

    Codepen example: N/A

    opened by matthias-ccri 0
  • Golden Layout have issue with loadlayour with saved config in 2.6.0

    Golden Layout have issue with loadlayour with saved config in 2.6.0

    When we save layout config in storage after that we get config from storage and load the layout that creates a code crash.

    it happens when I use dimension property defaultMinItemWidth because minItemWidth is deprecated in this version.

    opened by lovigupta 1
  • Popout URL redirect to handle hashes correctly

    Popout URL redirect to handle hashes correctly

    Addresses issue #809,

    Popout redirect fails with hash. We have an Angular App that uses hash's in the router, when popping out a window, the reloaded url is wrong.

    New behaviour: On popout, redirects : our_domain.com/path/#/dashboard?gl-window=gl-window-config-124etc

    Old behaviour: On popout, redirects, our_domain.com/path/?gli-window=gl-window-config-124etc#/dashboard (invalid url)

    opened by ohMorrissey 0
Releases(v2.6.0)
  • v2.6.0(Sep 26, 2022)

    Notable changes:

    • Remove browser from package #775 (@pbklink)
    • Fix add component tab positioning #776 (@pbklink)
    • Important Note: This PR removes the height property from .lm_drop_tab_placeholder in goldenlayout-base.less (and .scss). If your application uses a copy or derivative of this file, you will need to make the same change in your copy/derivative.
    • Improve handling of rounding when calculating areas #777 (@pbklink)
    • Fix #774 via #778, rework unload handling (@pbklink)
    • Fix #779 via #781 and #786, improve component sizing (@pbklink)
    • Update dependencies #784 (@pbklink)
    • Add support for proper ComponentItemConfig in DragSource #785 (@pbklink)
    Source code(tar.gz)
    Source code(zip)
    golden-layout-2.6.0.tgz(297.05 KB)
  • v2.5.0(Mar 5, 2022)

  • v2.4.0(Oct 23, 2021)

  • v2.3.0(Jul 19, 2021)

  • v2.2.1(May 28, 2021)

  • v2.2.0(May 15, 2021)

  • v2.1.2(Apr 30, 2021)

  • v2.1.1(Apr 15, 2021)

  • v2.1.0(Apr 5, 2021)

    v2.1.0

    Features

    • Readded popout functionality
    • Added popInOnClose function

    Bugfixes

    • Fixes deepExtend when run into multiple execution contexts
    • Fixes sided headers
    Source code(tar.gz)
    Source code(zip)
  • v2.0.3(Mar 30, 2021)

  • v2.0.2(Feb 27, 2021)

  • v2.0.1(Feb 23, 2021)

    2.0.1

    • Fix DragSource not working

    Caution: Breaking changes

    • newComponent() and addComponent() type functions in LayoutManager, Stack and RowOrColumn have a new title parameter. This parameter is optional however it is not the last optional parameter.
    • LayoutManager.createDragSource() has been renamed to LayoutManager.newDragSource(). This is to make it more obvious that it is paired with LayoutManager.removeDragSource()
    • LayoutManager.newDragSource() now only will create a ComponentItem. Its parameters have been changed to reflect that.
    • TypeScript definition has been updated to remove many private declarations which should not have been included.

    Note that LayoutManager.newDragSource() does not require LayoutConfig.settings.constrainDragToContainer to be set to false.

    Source code(tar.gz)
    Source code(zip)
    golden-layout-2.0.1.tgz(214.63 KB)
  • v2.0.0(Feb 8, 2021)

    Highlights

    • Complete rewrite to typescript
    • Rework the library and removed lots of old and unstable features
    • Only support modern browsers
    • Establish new community policy
    Source code(tar.gz)
    Source code(zip)
  • v1.5.9(Jul 28, 2017)

    Mostly a bugfix release:

    • Take border/padding of component into account when calculating size.
    • Update to make it possible to mutate event list while in an event handler.
    • Various memory leaks fixed.
    • A few Javascript updates; "use strict"-ability.
    • Add borderGrabWidth config.
    • Fix for some angular stuff.
    Source code(tar.gz)
    Source code(zip)
  • v1.5.8(May 12, 2017)

    • You can now drag panes to the far edges and have them dock there. Drag to within the last few pixels to see the new drop area.
    • Improvements to resize pane mouse cursors.
    • Middle click support.
    • Adds a 'shown' method to ItemContainer
    • LayoutManager.updateSize fixed to work with width and height
    • Responsive design; enabled by default, can be disabled with config.
    • Tab dropdown option: stacks can be displayed as dropdowns.
    • CSS now generated from less
    • Hidden items no longer updated to prevent reflows.

    Thanks to the many contributors who helped get this release together.

    Source code(tar.gz)
    Source code(zip)
  • v1.5.7(Jan 16, 2017)

    • Fix issues with ContentItems created from DragSources.
    • Fix AngularJS Routing issue
    • Add object to destroy call so we know what item is being destroyed.
    Source code(tar.gz)
    Source code(zip)
  • v1.5.6(Sep 28, 2016)

    Fix an issue dragging with buttons other than the left button. Makes createDragListener able to take a function to call as well as an ItemConfig, to support dynamic item configuration on drag.

    Source code(tar.gz)
    Source code(zip)
  • v1.5.5(Sep 22, 2016)

  • v1.5.4(Sep 22, 2016)

  • v1.5.3(Sep 19, 2016)

  • 1.5.1(Apr 15, 2016)

  • 1.5.0(Apr 10, 2016)

    Added support for ReactJS components Changed License to MIT Fixes hasHeaders=false error #76 Fixes jQuery Version mismatch #44 Fixes NPM dist path #42

    Source code(tar.gz)
    Source code(zip)
  • v1.0.8(Mar 5, 2015)

  • v1.0.7(Feb 15, 2015)

  • v1.0.6(Dec 14, 2014)

  • v1.0.5(Nov 17, 2014)

  • v1.0.4(Oct 18, 2014)

React-layout - Layout component for React. Handling the overall layout of a page

Layout Handling the overall layout of a page. ⚠️ Note: Implemented with flex lay

uiw 2 Jul 10, 2022
FlexLayout is a layout manager that arranges React components in multiple tab sets, tabs can be resized and moved.

FlexLayout is a layout manager that arranges React components in multiple tab sets, tabs can be resized and moved.

Caplin 649 Jan 7, 2023
React-Grid-Layout is a grid layout system much like Packery or Gridster, for React.

A draggable and resizable grid layout with responsive breakpoints, for React.

RGL 16.9k Jan 2, 2023
Layout-reactJS - Layout with React JS using NASA API

Layout with React JS using NASA API Website link on the web: Click Here Preview:

Anastacio Menezes 4 Feb 2, 2022
Auto Responsive Layout Library For React

autoresponsive-react Auto responsive grid layout library for React. Who are using ⭐ ⭐ ⭐ alibaba/ice ⭐ ⭐ ⭐ ice-lab/react-materials ⭐ ⭐ ⭐ ant-design/ant

达峰的夏天 1.5k Dec 15, 2022
The layout engine for React

Responsive, sortable, filterable and draggable grid layouts with React Design Principles ????‍?? Muuri-React is the React implementation of the amazin

Paolo Longo 274 Dec 21, 2022
A draggable and resizable grid layout with responsive breakpoints, for React.

React-Grid-Layout React-Grid-Layout is a grid layout system much like Packery or Gridster, for React. Unlike those systems, it is responsive and suppo

Samuel Reed 16.9k Jan 1, 2023
Resizable Flex layout container components for advanced React web applications

About Re-F|ex Re-F|ex is a React flex-based layout component library which I created because none of the components I found out there could satisfy my

Philippe Leefsma 532 Jan 8, 2023
Animated grid layout component for React

react-stonecutter Animated grid layout component for React, inspired by Masonry. Choose between CSS Transitions or React-Motion for animation. Demo In

Dan Train 1.2k Dec 24, 2022
Resizable Flex layout container components for advanced React web applications

About Re-F|ex Re-F|ex is a React flex-based layout component library which I created because none of the components I found out there could satisfy my

Philippe Leefsma 530 Dec 21, 2022
Photo layout editor for react

react-photo-layout-editor 사진 레이아웃을 편집하는 웹 프로그램입니다. This is photo layout editor for react 예전 Instagram blog( http://blog.instagram.com/ )에 있는 정렬된 이미지의

redgoose 115 Oct 7, 2022
This react component resize the layout of HTML using a handle

react-resize-layout This react component resize the layout of HTML using a handle Demo View the demo page Example View the example demo page npm insta

null 36 Nov 3, 2022
XMasonry: Masonry Layout for React JS

Responsive, minimalistic and full-featured native masonry layout (grid) for React JS.

Nikita Savchenko 79 Dec 2, 2022
Physical representation of layout composition to create declarative responsive layouts in React.

Atomic Layout is a spatial distribution library for React. It uses CSS Grid to define layout areas and render them as React components. This pattern e

Artem Zakharchenko 1.1k Dec 26, 2022
A powerful React component to abstract over flexbox and create any layout on any browser

FlexView A powerful React component to abstract over flexbox and create any layout on any browser. Install yarn add react-flexview Why The flexbox AP

buildo 277 Nov 11, 2022
Kilvin is a set of universal & primitive Layout Components for React.

Kilvin is a set of universal & primitive Layout Components for React.

Robin Weser 21 May 26, 2022
Simple Layout Field to offer a variety possibilities to react-jsonschema-forms

react-jsonschema-form-layout Just a small custom field for the awesome react-jsonschema-form. see DEMO Key features: support bootstrap's grid add non-

Audibene Labs 67 Jun 16, 2022
Pixel perfect layout inspection.

inspx Pixel perfect layout inspection. Built for React as a proof of concept. Setup Install the package: npm install inspx --save-dev Wrap the root of

rauno 1k Jan 5, 2023
Photo layout editor for react

react-photo-layout-editor 사진 레이아웃을 편집하는 웹 프로그램입니다. This is photo layout editor for react 예전 Instagram blog( http://blog.instagram.com/ )에 있는 정렬된 이미지의

redgoose 115 Oct 7, 2022