Golden Layout extension for WebSharper
This is the documentation for the WebSharper binding of the Golden Layout JavaScript library. The docs of the original library can be found here.
This documentation will go over the usage of the WebSharper extension and the differences between the original library and the extension's API.
Usage
Include the stylesheets
As with many other libraries, Golden Layout comes with its own stylesheets. In WebSharper,
the canonical way to include these extra resources is to use the Require
attribute on
the desired module
or function.
In this case, since the order of the Require
attributes counts, we include the
GoldenLayout.Resources.BaseCss
, and then either the DarkTheme
or the LightTheme
.
[<Require(typeof<GoldenLayout.Resources.BaseCss>)>]
[<Require(typeof<GoldenLayout.Resources.LightTheme>)>]
[<JavaScript>]
module Client =
// . . .
ContentItem config
You can create 5 different types of ContentItems: component
, react-component
,
column
, row
and stack
. The config object would have different special fields added
depending on the item's type. As this would not work very well in a statically typed
environment, the extension takes a slightly different approach:
- You have the
Item
struct with all common properties - You have a different config struct for each type with their special properties
- You combine them with a factory method to get the full ContentItem config
The result will be of a type called GeneralItemConfig
.
Note: the
GeneralItemConfig
is not intended for you to create the config with. It is used when the original library would return or pass aContentItem
config as a parameter. This means that in these cases you have to look out for the value of the config object'sType
property when deciding if you can ask for type-specific fields!
The factory methods are all static methods of the ItemFactory
type.
Method name | Signature |
---|---|
CreateComponent |
(Component * Item) -> GeneralItemConfig |
CreateReactComponent |
(ReactComponent * Item) -> GeneralItemConfig |
CreateStack |
(Stack * Item) -> GeneralItemConfig |
CreateColumn |
Item -> GeneralItemConfig |
CreateRow |
Item -> GeneralItemConfig |
The row
and column
types don't require any special config fields. The other config objects listed here:
Component
Field | Type | Required |
---|---|---|
ComponentName |
string |
required |
ComponentName |
obj |
- |
ReactComponent
Field | Type | Required |
---|---|---|
Component |
string |
required |
Props |
obj |
- |
Stack
Field | Type | Required |
---|---|---|
ActiveItemIndex |
int |
- |
Example
type State = {Text: string}
let helloComponent =
ItemFactory.CreateComponent(
Component(
componentName = "hello-component",
ComponentState = {Text = "Hello, "}
),
Item(
Title = "Hello",
IsClosable = false
)
)
let worldComponent =
ItemFactory.CreateComponent(
Component(
componentName = "world-component",
ComponentState = {Text = "World!"}
),
Item(
Title = "World!",
IsClosable = false
)
)
let mainContentItem =
ItemFactory.CreateRow(
Item(
Content = [|
helloComponent
worldComponent
|],
IsClosable = false
)
)
The rest of the API should be familiar from the original documentation.
Layout config
The config for layouts is much more analog with the original specification.
Layout
Field | Type | Required |
---|---|---|
Settings |
LayoutSettings |
- |
Dimensions |
LayoutDimensions |
- |
Labels |
LayoutLabels |
- |
Content |
GeneralItemConfig [] |
- |
The usage of these fields can be found here in the original docs.
Instantiation
Now that we know how to describe our layout and content item configs, we can finally
instantiate the main layout manager class which is called GoldenLayout
. You can
either pass the constructor a Layout
config, or a Layout
config and a JQuery
or Dom.Element
as the container to create the layout in. Otherwise, the DOM of the
layout will be appended to the <body>
of your HTML file. Let's look at an example
using the configs defined before:
let layoutManager =
GoldenLayout(
Layout(
Content = [|
mainContentItem
|]
)
)
Registering components
When we have our layout manager ready, we can start to register our components. This means that we will bind a function to every component name, which function when given the container and the state of the component, will produce the content of the component into the container.
layoutManager.RegisterComponent(
"hello-component",
fun (container, s) ->
let state = s :?> State
(h3 [text state.Text]).Html
|> container.GetElement().Html
|> fun jq -> jq.Ignore
layoutManager.RegisterComponent(
"world-component",
fun (container, s) ->
let state = s :?> State
(h2 [text state.Text]).Html
|> container.GetElement().Html
|> fun jq -> jq.Ignore
)
Initialising
We've created our layout manager and registered our components, but the layout won't work just yet. We have to initialise it manually.
layoutManager.Init()
The layouts should appear now as described in their configs.
Events
The GoldenLayout
, ContentItem
, Container
and BrowserWindow
classes all
inherit the functionality of the EventEmitter
class with all of them having
their respective events, too. To make things easier and faster, these classes'
respective events have been collected into enums called {ClassName}Event
.
All methods of the EventEmitter
class which take an "event"
as parameter
have been overloaded for these enums. You can still choose to pass the event
name as a string
, but using these enums will make your code safer.
Here's an example:
let layoutManager =
layoutManager.On(
LayoutEvent.Initialised, //an event from the LayoutEvent enum
fun (params: obj []) -> //the callback function
Console.Log("The Layout has been initialised.")
Console.Log(params)
)
Examples
For fully working examples, visit these links: