- Native popup windows
- Full touch support
- Virtual components
- Comprehensive API
- Powerful persistence
- Completely themeable
- Works in modern browsers (Firefox, Chrome)
- Reponsive design
Golden Layout is shipped via NPM. Use the following commands to install it into an application package:
npm i golden-layout
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:
npm install
ornpm ci
(recommended) to install required dependenciesnpm run build
to generate the distribution (dist
subfolder). This script will:- delete the existing
lib
anddist
folders - compile the TypeScript code
- generate the rolled up TypeScript definition files (
index.d.ts
andgolden-layout-untrimmed.d.ts
) - generate source map
- copy the style files to the
dist
folder
- delete the existing
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.
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 itnpm 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/
We provide different types of single file bundles for easier consumption without toolchain in-place. To do this, run npm run build:bundles
, afterwards find your bundled files in dist/bundle/
.
Bundles are not built by default and are not included in the NPM package, we recommend everyone to consume the library through NPM and webpack.
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:
- Run the
npm link
from a shell in the golden-layout source repository top level folder. - 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.
Run npm install
to remove the npm link.
The following information sources are available which can be used to learn how to use Golden Layout:
- Golden Layout website
- This readme
- CodePen examples
The Golden Layout website documents version 1 of Golden Layout. While substantial changes were made in version 2, this website can still be used to gain a broad understanding of Golden Layout.
This readme can be used to learn about features introduced in Version 2. It also describes the changes necessary to migrate an application from version 1 to version 2.
The following CodePen examples are available:
- Adding items to a predefined layout
A basic example showing how Golden Layout is set up and how to add a new item to a layout.
Golden Layout binds to components and then controls their position, size and visibility (positioning) so that they fit within a layout. There are 4 ways Golden Layout can bind to a component:
- Embedding via Registration (classic)
A component's constructor/factory is registered with Golden Layout. Golden Layout will instantiate an instance when required. The constructor/factory will add the component's root HTML element within Golden Layout's own DOM hierarchy sub-tree. This is the classic Golden Layout binding method. With this binding method an ancestor of the component's root HTML element could be reparented if the layout changes. - Embedding via Events
Components are obtained on demand by events. An event handler will construct or otherwise fetch the component and return it. The event handler will also add the component's root HTML element within Golden Layout's own DOM hierarchy sub-tree. This is the binding method introduced in version 2. - Virtual via Registration
A component's constructor/factory is registered with Golden Layout. Golden Layout will instantiate an instance when required. The component will use the same positioning as virtual components however Golden Layout will handle all the events internally. - Virtual via Events (Virtual Components)
With virtual components, Golden Layout never interacts directly with components. The application controls the construction/allocation, destruction/deallocation and positioning of components. Golden Layout will advise the application when components are needed and no longer needed via events. It will also advise about components' positioning via events. This allows an application to control the placement of components in the DOM hierarchy and components' root HTML element's ancestors are not reparented when the layout is changed.
Registering a component and specifying static positioning is the classic GoldenLayout approach to binding components. The components are registered with GoldenLayout and specify a constructor or callback function used to create a component whenever a new instance is needed in the layout. When the constructor or callback is invoked, it is passed a container object which includes a HTML element. The constructor or callback will create the object and make its top level HTML element a child of the container's HTML element. The component is then part of the Golden Layout's DOM hierarchy. Whenever the layout is re-arranged, the GoldenLayout DOM is adjusted to reflect the new layout hierarchy. Effectively this involves the ancestors of components' root HTML elements being reparented when a layout is changed.
The following functions can be used to register components.
GoldenLayout.registerComponent()
GoldenLayout.registerComponentConstructor()
GoldenLayout.registerComponentFactoryFunction()
GoldenLayout.registerComponentFunction()
GoldenLayout.registerGetComponentConstructorCallback()
To give applications more control over the allocation of components, you can bind components with events instead of registration. If a handler is assigned to the event VirtualLayout.bindComponentEvent
it will be fired whenever a new component is needed. The handler should:
- create or fetch the component,
- make sure its top level HTML elements are made children of
container.element
, - return the component inside a
BindableComponent
interface withvirtual: false
.
When a component is removed from Golden Layout it will be necessary to remove the component's top level HTML elements as children of container.element
. Other component 'tear-down' actions may also be required. These actions can be carried out in either the VirtualLayout.unbindComponentEvent
event or the component container's beforeComponentRelease
event (or both). Both these events will be fired (if handlers are assigned) when a component is no longer needed in Golden Layout.
With virtual components, Golden Layout knows nothing about components and does not include the component's HTML elements in its own DOM hierarchy. Instead, whenever a component needs its position, size or visibility changed, Golden Layout will fire events which allow the application to change a component's position, size or visibility. This is analogous to virtual grids where strings and other content to be displayed in a grid, are not included within the grid. Instead the grid fires events whenever it needs to display content. The application will return the required content.
Virtual Components has the following advantages:
- Components and their ancestors are not reparented when a layout is changed. This avoids breaking iframe, sockets, etc.
- It is no longer necessary to extract the top level HTML element from a component.
- Applications using frameworks with their own component hierarchy, such as Angular and Vue, no longer have to break their component hierarchy to insert Golden Layout. The framework's methodology for handling parent/child relationships can be maintained even with the components which Golden Layout is positioning. (Teleporting component's HTML elements is no longer necessary)
- Applications typically bind a component's top level HTML element to the Golden Layout root element. Debugging becomes easier as the DOM hierarchy relevant to your application is a lot shallower.
With Virtual Components the following events need to be handled:
-
VirtualLayout.bindComponentEvent: (container, itemConfig) => ComponentContainer.BindableComponent
Fired whenever a GoldenLayout wants to bind to a new component. The handler is passed the container and the item's resolved config. Typically, the handler would:- create or fetch the component using
itemConfig
, - get the the component's top level HTML component,
- ensure this element has
absolute
position, - make the element a child of Golden Layout's root HTML element,
- store the component in a map using
container
as the key, - add handlers to the container's
virtualRectingRequiredEvent
andvirtualVisibilityChangeRequiredEvent
events, - return the component in an
BindableComponent
interface withvirtual: true
.
Example:
private handleBindComponentEvent(container: ComponentContainer, itemConfig: ResolvedComponentItemConfig) { // Use ResolvedComponentItemConfig.resolveComponentTypeNamecan to resolve component types to a unique name const componentTypeName = ResolvedComponentItemConfig.resolveComponentTypeName(itemConfig); if (componentTypeName === undefined) { throw new Error('handleBindComponentEvent: Undefined componentTypeName'); } const component = this.createVirtualComponent(container, componentTypeName, itemConfig.componentState); const componentRootElement = component.rootHtmlElement; this._layoutElement.appendChild(componentRootElement); this._boundComponentMap.set(container, component); container.virtualRectingRequiredEvent = (container, width, height) => this.handleContainerVirtualRectingRequiredEvent(container, width, height); container.virtualVisibilityChangeRequiredEvent = (container, visible) => this.handleContainerVisibilityChangeRequiredEvent(container, visible); return { component, virtual: true, }; }
- create or fetch the component using
-
VirtualLayout.unbindComponentEvent: (container) => void
Fired when a component is removed from Golden Layout. The handler is passed the container. Typically, the handler would:- find the component in the map using
container
as the key, - remove it as a child from Golden Layout's root HTML element,
- remove it from the map.
Example:
private handleUnbindComponentEvent(container: ComponentContainer) { const component = this._boundComponentMap.get(container); if (component === undefined) { throw new Error('handleUnbindComponentEvent: Component not found'); } const componentRootElement = component.rootHtmlElement; if (componentRootElement === undefined) { throw new Error('handleUnbindComponentEvent: Component does not have a root HTML element'); } this._layoutElement.removeChild(componentRootElement); this._boundComponentMap.delete(container); }
- find the component in the map using
-
LayoutManager.beforeVirtualRectingEvent: () => void
This event does not need to be handled. However it can be used to optimise positioning of components. Whenever a layout is changed, it may be that several components need to be repositioned. This event will be fired whenever one or more components need to be positioned as the result of one layout change. Typically it is used to get the position of Golden Layout's root HTML element, usinggetBoundingClientRect()
. This can then be cached for use when each component's position needs to be calculated.Example:
private handleBeforeVirtualRectingEvent(count: number) { this._goldenLayoutBoundingClientRect = this._layoutElement.getBoundingClientRect(); }
-
ComponentContainer.virtualRectingRequiredEvent: (container, width, height) => void;
Fired when a component's position and/or size need to be changed. The handler is passed the container and the component's required width and height. Typically, the handler would:- find the component in the map using
container
as the key, - get the Golden Layout's root HTML element's position using
getBoundingClientRect()
, (Alternatively, it can used the position calculated by the handler for thevirtualRectingRequiredEvent
event.) - get the container's position using
getBoundingClientRect()
, - calculate the container's position relative to Golden Layout's root HTML element position.
- accordingly, update the following properties in the component's top level HTML element:
left
top
width
height
Example:
private handleContainerVirtualRectingRequiredEvent(container: ComponentContainer, width: number, height: number) { const component = this._boundComponentMap.get(container); if (component === undefined) { throw new Error('handleContainerVirtualRectingRequiredEvent: Component not found'); } const rootElement = component.rootHtmlElement; if (rootElement === undefined) { throw new Error('handleContainerVirtualRectingRequiredEvent: Component does not have a root HTML element'); } const containerBoundingClientRect = container.element.getBoundingClientRect(); const left = containerBoundingClientRect.left - this._goldenLayoutBoundingClientRect.left; rootElement.style.left = this.numberToPixels(left); const top = containerBoundingClientRect.top - this._goldenLayoutBoundingClientRect.top; rootElement.style.top = this.numberToPixels(top); rootElement.style.width = this.numberToPixels(width); rootElement.style.height = this.numberToPixels(height); }
- find the component in the map using
-
ComponentContainer.virtualVisibilityChangeRequiredEvent: (container, visible) => void;
Fired when a component's visibility needs to be changed. The handler is passed the container and a boolean specifying visibility. Typically, the handler would:- find the component in the map using
container
as the key, - change its visibility using the
display
property in the component's top level HTML element.
Example:
private handleContainerVisibilityChangeRequiredEvent(container: ComponentContainer, visible: boolean) { const component = this._boundComponentMap.get(container); if (component === undefined) { throw new Error('handleContainerVisibilityChangeRequiredEvent: Component not found'); } const componentRootElement = component.rootHtmlElement; if (componentRootElement === undefined) { throw new Error('handleContainerVisibilityChangeRequiredEvent: Component does not have a root HTML element'); } if (visible) { componentRootElement.style.display = ''; } else { componentRootElement.style.display = 'none'; } }
- find the component in the map using
-
ComponentContainer.virtualZIndexChangeRequiredEvent: (container, logicalZIndex, defaultZIndex) => void
Fired when a component's z-index needs to be changed. The handler is passed the container and a logical z-index and the default style z-index. Typically, the handler would:- find the component in the map using
container
as the key, - change its z-index to the default style z-index specified in
defaultZIndex
.
Example:
private handleContainerVirtualZIndexChangeRequiredEvent(container: ComponentContainer, logicalZIndex: LogicalZIndex, defaultZIndex: string) { const component = this._boundComponentMap.get(container); if (component === undefined) { throw new Error('handleContainerVirtualZIndexChangeRequiredEvent: Component not found'); } const componentRootElement = component.rootHtmlElement; if (componentRootElement === undefined) { throw new Error('handleContainerVirtualZIndexChangeRequiredEvent: Component does not have a root HTML element'); } componentRootElement.style.zIndex = defaultZIndex; }
- find the component in the map using
The apitest application demonstrates how virtual components are implemented.
When using virtual components, think of Golden Layout as more of an engine calculating position rather than actually positioning components. This binding method requires more work to set up than other binding methods. However it offers more flexibility and opens up more design opportunities. For example with virtual components, any HTML element could be the parent for your components (not just the Golden Layout container). You can even have different parents for different components. This allows, for example, some of your components have one parent, and the others a different parent. They could then inherit different CSS or handle event propagation differently.
These events give applications a lot of flexibility with positioning components in Golden Layout - but at the expense of more effort of integrating into Golden Layout. It is however, possible to get the same benefits of Virtual Components with just registering a component. In this case, a component will be registered as in classic approach to Golden Layout binding, however, within Golden Layout, the component will be handled like a virtual component. Golden Layout will internally handle the necessary events.
Existing applications using register functions in Golden Layout can easily be updated to use virtual binding by:
- The register functions have a new parameter
virtual
. By default, this isfalse
, specifying the classic binding in Golden Layout. Set this totrue
to specify that components of that type should be implemented internally as virtual components. - Components need to have a getter:
rootHtmlElement
which returns the component's root HTML element. Components written in TypeScript should implement theGoldenLayout.VirtuableComponent
interface. - Components'
rootHtmlElement
element need to have itsoverflow
CSS property set to hidden. - Ensure that the Golden Layout container HTML element is positioned (ie. its position property is not
static
).
With these changes, applications can continue to use Golden Layout as they are now however Golden Layout will internally use virtual component binding.
Please note there will be a couple of minor behaviour changes:
- Golden Layout will ensure a component's root HTML element has position type
absolute
. - Golden Layout will modify the height and width of the root HTML element. In embedding bindings, Golden Layout modified the height and width of the container element - not the component's root HTML Element. If your application also sets the height or width of a components root HTML element, you will need to modify your design. This can easily be done by giving the current root HTML element a new parent element and making this parent the new root HTML element for the component. Your component logic can continue to use the existing element while Golden Layout uses the new root HTML element.
- Golden Layout will modify the z-index of the component's root HTML element.
Also note that 'virtual via registration' binding is not supported by the GoldenLayout.registerGetComponentConstructorCallback()
registration function.
An application can use multiple methods of binding components for different component types. Whenever a component needs to be bound, Golden Layout will try to bind in the following order:
- First check if its type has been registered. If so, it will bind using that registration.
- Check whether there is a
bindComponentEvent
handler. If so, this event will be used to bind it as a virtual component. - Check whether there is a
getComponentEvent
handler. If so, this event will be used to bind the component statically within the Golden Layout DOM. This method is deprecated. - If none of the above, then an exception will be raised.
If you use both 'Virtual via Events' and 'Embedding via Events', then the unbindComponentEvent
handler can use the ComponentContainer.virtual
field to determine which of these binding methods was used for a component.
The inheritance hierarchy for the Golden Layout class is: LayoutManager
-> VirtualLayout
-> GoldenLayout
.
The VirtualLayout
class implements all the Golden Layout functionality except for the register functions. If you only intend to use virtual components using the bindComponentEvent
, you can create an instance of VirtualLayout
instead of GoldenLayout
.
- Quick and easy
Use 'Embedding via Registration'. The classic way of using Golden Layout. - Backwards compatibility
If your existing application uses the Golden Layout registration functions, then it will automatically use 'Embedding via Registration' without any changes. - Deprecated
getComponentEvent
To quickly get rid of this deprecation, use 'Embedding via Events'. - Easy virtual component bindings Use 'Virtual via Registration' to get the advantages of Virtual Component binding with minimal changes to applications.
- Maximum design flexibility
Use 'Virtual via Events' (Virtual Components).
Typically frameworks wrap HTML elements with their own components. Instead of an application being a tree of HTML elements, it is a tree of framework components, each of which wrap an HTML element.
With the traditional embedding via events component binding, Golden Layout injects itself into this the tree of HTML elements. However with frameworks, this interferes with the tree of components. Advanced framework techniques are required to work around this problem.
Virtual via events component binding allows Golden Layout to be used within framework applications without interfering with the tree of components. This is the recommended approach to binding components to Golden Layout in framework applications.
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.
This example demonstrates how Golden Layout can be used with Angular using either embedding via events or virtual via events component binding.
The following snippets of code demonstrate how Golden Layout can be used in Vue.
These snippets use embedding via events binding. It may be preferable to use virtual via events binding (ie Virtual Components). A Pull Request from a Vue user demonstrating using Vue with virtual components would be appreciated.
import { GoldenLayout, LayoutConfig } from 'golden-layout';
import { onMounted, ref, shallowRef } 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(
createComponent: (type: string, container: HTMLElement) => ComponentContainer.Component,
destroyComponent: (container: HTMLElement) => void,
config?: LayoutConfig
) {
const element = shallowRef<HTMLElement | null>(null);
const layout = shallowRef<GoldenLayout | null>(null);
const initialized = ref(false);
useDocumentReady(() => {
if (element.value == null) throw new Error('Element must be set.');
const goldenLayout = new GoldenLayout(element.value);
goldenLayout.bindComponentEvent = (container, itemConfig) => {
const { componentType } = itemConfig;
if (typeof componentType !== 'string') throw new Error('Invalid component type.');
const component = createComponent(componentType, container.element);
return {
component,
virtual: false,
}
}
goldenLayout.unbindComponentEvent = container => {
destroyComponent(container.element);
}
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 };
}
<template>
<div ref="element" style="width: 100%; height: 75vh">
<teleport
v-for="{ id, type, element } in componentInstances"
:key="id"
:to="element"
>
<component :is="type"></component>
</teleport>
</div>
</template>
<script lang="ts">
import { useGoldenLayout } from "@/use-golden-layout";
import { defineComponent, h, shallowRef } from "vue";
import "golden-layout/dist/css/goldenlayout-base.css";
import "golden-layout/dist/css/themes/goldenlayout-dark-theme.css";
const Test = defineComponent({ render: () => h('span', 'It works!') });
const components = { Test, /* other components */ };
export default defineComponent({
components,
setup() {
interface ComponentInstance {
id: number;
type: string;
element: HTMLElement;
}
let instanceId = 0;
const componentTypes = new Set(Object.keys(components));
const componentInstances = shallowRef<ComponentInstance[]>([]);
const createComponent = (type: string, element: HTMLElement) => {
if (!componentTypes.has(type)) {
throw new Error(`Component not found: '${type}'`);
}
++instanceId;
componentInstances.value = componentInstances.value.concat({
id: instanceId,
type,
element,
});
};
const destroyComponent = (toBeRemoved: HTMLElement) => {
componentInstances.value = componentInstances.value.filter(
({ element }) => element !== toBeRemoved
);
};
const { element } = useGoldenLayout(createComponent, destroyComponent, {
root: {
type: "column",
content: [
{
type: "component",
componentType: "Test",
},
{
type: "component",
componentType: "Test",
},
],
},
});
return { element, componentInstances };
},
});
</script>
For other frameworks, use Virtual via events component binding and set up the handlers using the guide in this section. Once this is done, functions that create components can be used. For example:
LayoutManager.loadLayout()
LayoutManager.addComponent()
Popouts are supported, although the scope is more limited than in the original v1. Popouts are enabled by default for all content items. Popouts are disabled by either setting { popout: false }
in the header
configuration or when a component is not closable. Also, as a popout user, make sure to register all component types before initializing the golden-layout instance in your child windows.
Popout examples are available in the standard
and tabDropdown
layouts within the apitest application.
EventHub can be used to broadcast messages and events to all windows. The LayoutManager.eventHub.emitUserBroadcast() function is used to broadcast messages. Messages can be received by listening to “userBroadcast” events. For example:
layoutManager.eventHub.on('userBroadcast', (...ev: EventEmitter.UnknownParams) => {
// respond to user broadcast event
});
See event-component.ts in apitest for a complete example of broadcasting user messages.
- The EventHub is restricted to
userBroadcast
events, other event types will not be broadcasted between windows. - This means the you have to take care of propagating state changes between windows yourself.
Components can have focus. This is analagous to HTML Elements having focus.
Only one component in a layout can have focus at any time (or alternatively, no component has focus). Similarly to HTML elements, a component will be focused when you click on its tab. You can programatically give a component focus by calling the focus()
method on its container. Likewise, you can remove focus from a container by calling ComponentContainer.blur()
.
Clicking on HTML within a component will not automatically give a Golden Layout component focus. However this can be achieved by listening to the bubbling click
and/or focusin
events and calling ComponentContainer.focus()
in these events' handlers. The apitest
demonstrates this technique.
A focused component's tab and header HTML elements will contain the class lm_focused
. This can be used to highlight the focused tab and or header. The goldenlayout-dark-theme.less
theme that ships with Golden Layout (and is used by apitest
) will set the background color of a focused tab to a different color from other tabs. If you do NOT want focused tabs to be highlighted, ensure that the lm_focused
selector is removed from the relevant css/less/scss used by your application.
LocationSelectors specify the location of a component in terms of a parent and a index. LocationSelectors are useful for specifying where a new ContentItem should be placed.
A LocationSelector
does not specify the parent directly. Instead it specifies how the parent is to be searched for. It has the type:
export interface LocationSelector {
typeId: LocationSelector.TypeId;
index?: number;
}
typeId
specifies the algorithm used to search for a parent.
index
is used by the algorithm to work out the preferred child position under the parent.
Some LocationSelector.TypeId
will always find a location. Eg: LocationSelector.TypeId.Root
is guaranteed to find a location. Others may not find a location. Eg: LocationSelector.TypeId.FirstStack
will not find a location if a layout is empty.
The LayoutManager.addComponentAtLocation()
and LayoutManager.newComponentAtLocation()
use an array of LocationSelectors to determine the location at which a new/added component will be installed. These functions will attempt to find a valid location starting with the first element in the LocationSelectors array. When a valid location is found, that location will be used for the new component. If no valid location is found from the LocationSelectors in the array, then the component will not be added.
The LayoutManager.addComponent()
and LayoutManager.newComponent()
use a default LocationSelectors array. The last element in this default array is a LocationSelector of type LocationSelector.TypeId.Root
. So this array is guaranteed to find a location. Accordingly, LayoutManager.addComponent()
and LayoutManager.newComponent()
will always succeed in adding a component.
This default LocationSelectors array is available at LayoutManager.defaultLocationSelectors
. An alternative predefined array is available at LayoutManager.afterFocusedItemIfPossibleLocationSelectors
.
This version is a substantial change from the previous (1.5.9) version. The change can be summarised as:
- The code has been ported to TypeScript
- The primary focus of maintenance will be on reliability.
Before migrating from version 1, it is important to review the following:
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
orpublic
. Onlypublic
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)
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.
Configs are now strongly typed. In addition, GoldenLayout now has "Configs" and "Resolved Configs"
- 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 isLayoutConfig.saveLayout()
which returns a "Resolved Config". - 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:
ItemConfig
This specifies the config for a content item.LayoutConfig
(previously theConfig
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:
GoldenLayout.registerComponent()
(deprecated)GoldenLayout.registerComponentConstructor()
GoldenLayout.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:
minifyConfig()
ReplacesLayoutManager.minifyConfig()
unminifyConfig()
ReplacesLayoutManager.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
is now a distinct class which is a descendant of the VirtualLayout
class, which in turn is a descendant of the LayoutManager
class. Your application should always create an instance of either GoldenLayout
or VirtualLayout
.
The GoldenLayout
and VirtualLayout
constructors takes 3 optionals parameters:
- The HTML element which contains the GoldenLayout instance. If this is not specified, GoldenLayout will be placed under
body
. - The
bindComponentEvent
event handler. - The
unbindComponentEvent
event handler.
Note that the initial Layout is no longer specified in this constructor. Instead it is loaded with LayoutManager.loadLayout()
(see below).
The GoldenLayout class now handles component registration. LayoutManager no longer includes any component registration functions. The following changes to registration functions have been made:
registerComponentConstructor()
(new function)
Same as previousregisterComponent()
however only used when registering a component constructor.registerComponentFactoryFunction
(new function)
Same as previousLayoutManager.registerComponent()
however only used when registering a call back function (closure) for creating components.- Do not use
registerComponent()
. Use the newregisterComponentConstructor()
orregisterComponentFactoryFunction()
instead.
- Do not construct an instance of LayoutManager. Construct an instance of GoldenLayout (see above).
- Do not call
init()
. CallLayoutManager.loadLayout()
instead. loadLayout()
(new function)
Will load the new layout specified in itsLayoutConfig
parameter. This can also be subsequently called whenever the GoldenLayout layout is to be replaced.saveLayout()
(new function)
Saves the current layout as aLayoutConfig
. Replaces the existingtoConfig()
function.- Do not uses
minifyConfig()
ofunminifyConfig()
functions. Use the respective functions inResolvedLayoutConfig
. - Do not call
toConfig()
. CallLayoutManager.saveLayout()
instead. setSize()
(new function)
Sets the size of the GoldenLayout instance in pixels. Replaces the existingupdateSize()
function.- Do not use
updateSize()
. Use the newLayoutManager.setSize()
instead. rootItem
(new property) Specifies the root content item of the layout (not the Ground content item).- Do not use
root
. This has been replaced with the internal propertygroundItem
. You probably want to use the newrootItem
instead. 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
orblur
events will be emitted as appropriate unless thesuppressEvent
parameter is set to true.clearComponentFocus()
which removes any existing component item focus. If focus is removed, ablur
event will be emitted unless thesuppressEvent
parameter is set to true.
getComponentEvent
Now implemented in the VirtualLayout class but has been deprecated. UseVirtualLayout.bindComponentEvent
instead.releaseComponentEvent
(new event)
Now implemented in the VirtualLayout class but has been deprecated. UseVirtualLayout.unbindComponentEvent
instead.- See Binding Components section for more information about new events related to binding components.
AbstractContentItem
has been renamed toContentItem
config
property has been removed. Use the toConfig() method instead (as recommended in the original GoldenLayout documentation).- Some of the previous
config
properties such asid
andtype
are now available as properties ofContentItem
or its descendants (where appropriate). id
now has typestring
. (It used to bestring | string[]
.)ItemContainer
has been renamed toComponentContainer
Component
has been renamed toComponentItem
. "Component" now refers to the external component hosted inside GoldenLayoutRoot
has been renamed toGroundItem
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 withLayoutManager.rootItem
.Stack.getActiveContentItem()
andStack.setActiveContentItem()
have been renamed to respectiveStack.getActiveComponentItem()
andStack.setActiveComponentItem()
ContentItem.select()
andContentItem.deselect()
have been removed. Use the newComponentItem.focus()
andComponentItem.blur()
instead.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, afocus
event will be emitted (unless suppressEvent parameter is set to true).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, ablur
event will be emitted (unless suppressEvent parameter is set to true).
element
(new property - replacesgetElement()
)
Returns HTMLElement which hosts component- Do not use
getElement()
. Use the newelement
property instead initialState
(new getter)
Gets the componentState of theComponentItemConfig
used to create the contained component.stateRequestEvent
(new event)
If set,stateRequestEvent
is fired whenever GoldenLayout wants the latest state for a component. CallingLayoutManager.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 insetState()
will be saved.beforeComponentRelease
(new EventEmitter event)
beforeComponentRelease
is emitted on the container before a component is released. Components can use this event to dispose of resources.- Do not use
getState()
unless you are using the deprecatedsetState()
. UseComponentContainer.initialState
getter if you have migrated to the newComponentContainer.stateRequestEvent
. setState()
has been marked as deprecated. If possible, use the newstateRequestEvent
event instead.replaceComponent()
allows you to replace a component in a container without otherwise affecting the layout.- See Binding Components section for more information about new events related to binding components.
Several properties and functions have been renamed in header.ts
and tab.ts
. Please search for "@deprecated" in these files for these changes.
- All DOM events are now propagated so that they can be handled by parents or globally.
- preventDefault() is not called by any event listeners.
- Bubbling Events are now emitted with the parameter EventEmitter.BubblingEvent (or descendant)
- 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.
undefined
is used instead ofnull
for new properties, events etc. Some internals have also been switched to useundefined
instead ofnull
. Existing properties usingnull
mostly have been left as is however it is possible that some of these internal changes have affected external properties/events/methods.
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.
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:
index.d.ts
which contains only public API elements. Applications should use this declaration file to access the library.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.