Customizations with Platform API

While you can use the UI features provided by the Platform API without modification, there are a few ways you can change the way they look or behave.

  • Changing the look of standard windows via CSS
  • Using modal windows
  • Replacing standard windows with custom ones
  • Changing the look of Layouts via CSS
  • Changing keyboard shortcuts

Window customization

Windows created using the OpenFin Platform API act as a host (or container) for OpenFin Views. If your content is rendered in Views, your window can be used to display UI controllers, and acts as a “frame” within which views are drawn.

OpenFin standard window

The OpenFin Platform API includes OpenFin’s standard window, which has typical window controls (close, minimize, maximize) and some style customization.

As the name suggests, the standard window is used as the default window you get if you don’t specify the window’s URL upon creation.

Example of OpenFin’s standard windowExample of OpenFin’s standard window

Example of OpenFin’s standard window

Standard window customization

You can easily apply your own stylesheet to the standard window by specifying the stylesheetUrl property within defaultWindowOptions in your manifest. The path or URL must be absolute, not relative.

{
    "platform": {
        "uuid": "example_platform",
        "defaultWindowOptions": {
            "stylesheetUrl": "full-url-to-css-stylesheet"
        }
    },
    "snapshot": {
        ...
    }
}

📘

Overriding standard frame CSS selectors

To get an idea of the selectors that are available for you to override, take a look at the Platform style examples or inspect the window using Chrome Developer Tools.

Modal windows

You can create windows that are modal relative to a parent window. This enables you to create the same effect as modal dialog boxes in native applications. To create a modal window, add modalParentIdentity to the window options when you create it. It's also important, for usability, to set autoShow to true; otherwise, it could be hidden but still blocking interaction with its parent window.

let winOption = {
        name:'child',
        defaultWidth: 300,
        defaultHeight: 300,
        url: 'https://cdn.openfin.co/docs/javascript/stable/tutorial-Window.create.html',
        frame: true,
        autoShow: true,
        modalParentIdentity: {uuid: "OpenfinPOC", name: "OpenfinPOC"}
    };
fin.Window.create(winOption);

Complete window customization

You can also overwrite OpenFin's standard window and "bring your own window." To do so, specify the url property as a window option in your manifest. This HTML file must contain a div component where you want the layout to be rendered. Use this div as the containerId property when you call Layout.init to initialize the Layout in the window and load the views. A url can also be specified in windowOptions in a snapshot, or when launching a snapshot via other methods; the URL must be absolute, not relative.

{
    "platform": {
        "uuid": "example_platform",
        "defaultWindowOptions": {
            "url": "full-url-to-html-file"
        }
    },
    "snapshot": {
        ...
    }
}
// Layout.init must be called in the custom window to initialize the Layout and 
// load the views.  Call init on DOMContentLoaded or after the window is setup 
// and the target div element has been created
window.addEventListener('DOMContentLoaded', () => {
    fin.Platform.Layout.init({containerId: 'id-of-div'});
});

📘

defaultWindowOptions.stylesheetUrl and custom windows

Note that defaultWindowOptions.stylesheetUrl is supported only for overriding standard window styles. If you are providing a custom window, include your stylesheets in your custom HTML document.

Using keyboard shortcuts

OpenFin defines and implements a set of optional commands and behaviors specific to UI objects created with the Platform API. You can configure keyboard shortcuts for the commands in the commands property of the platform object in your manifest. For details about the properties of command items, see the hotkeys option on Window.

{
    "platform": {
        "uuid": "example_platform",
        "defaultWindowOptions": {
            ...
        },
        "commands": [
            {
                "command": "stack.nextTab",
                "keys": "Ctrl+T"
            }
        ]
    },
    "snapshot": {
        ...
    }
}

Available commands for keyboard shortcuts

Some of the commands are enabled by default. The following table shows the list of commands enabled by default and their keyboard shortcuts:

Command name

Default shortcut

Description

stack.closeTab

None

Closes the currently focused tab.

stack.nextTab

Ctrl+Tab

Switches to the next tab in the stack.

stack.nth-tab

Ctrl+1 through Ctrl+9

Switches to the nth tab in the current stack.

stack.previousTab

Ctrl+Shift+Tab

Switches to the previous tab in the current stack.

view.detach

Ctrl+Shift+D

Pops the current view out of the window.

view.focusDown

Ctrl+Shift+Down

Moves the focus to the view below currently focused one.

view.focusLeft

Ctrl+Shift+Left

Moves the focus to the view to the left of currently focused one.

view.focusRight

Ctrl+Shift+Right

Moves the focus to the view to the right of currently focused one.

view.focusUp

Ctrl+Shift+Up

Moves the focus to the view above currently focused one.

view.zoomIn

Ctrl+=

Zooms in on the contents of the current view

view.zoomInSecondary (v24+)

Ctrl+Shift+=

Zooms in on the contents of the current view

view.zoomOut

Ctrl+-

Zooms out on the contents of the current view.

view.zoomOutSecondary (v24+)

Ctrl+Shift+=

Zooms out on the contents of the current view.

view.zoomReset

Ctrl+0

Resets zoom level of the current view contents.

Keyboard command example

{
    "command": "view.detach",
    "keys": "Ctrl+D"
}
/*
To disable a command you can simply omit its 'keys' property
*/

{
    "command": "stack.zoomIn"
}
/*
You can disable all default commands using the 'disableDefaultCommands' 
property on your 'platform' object. Once you do that, you can enable 
only the ones you need individually:
*/

{
    "platform": {
        ...,
        "disableDefaultCommands": true,
        "commands": [
            {
                "command": "stack.nextTab",
                "keys": "Ctrl+T"
            }
        ]
    }
    ...
}

Layout CSS classes

When using a custom CSS file to modify the layout's appearance, you can extend or overwrite the internal CSS classes used by the layout to achieve a customized layout look and feel.

The following are the main classes used by the Layout components:

  • .lm_root: The top-level container of all other containers
  • .lm_row: Represents a row of layout containers
  • .lm_column: Represents a column of layout containers
  • .lm_stack: Represents a pile of tabs stacked on top of each other
    • .lm_header: Contains lm_tabs, lm_controls, lm_tabdropdown_list
      • .lm_tabs: Contains all tabs in the current stack
        • .lm_tab: Contains the tab cap title and buttons
      • .lm_controls: Unused
      • .lm_tabdropdown_list: Contains all dropdown tabs in the current stack
        • .lm_tab: Contains the tab cap title and buttons
    • .lm_items: Contains all item containers in the stack
      • .lm_item_container: A placeholder div on top of which views are drawn. Show an error message if a view fails to render.

Customizing platform behavior

The Platform Provider is the communication hub that coordinates among all windows in a Platform. This Provider runs in a hidden window. By creating a custom Provider, you can overwrite or extend default Platform behavior.

Provide custom HTML for the Provider window

Because the Provider runs in a normal (hidden) OpenFin window, it needs an HTML document. To provide your own document, add a providerUrl property to your Platform's manifest:

// app.json
{
    "platform": {
        "uuid": "my-uuid",
        ...,
        "providerUrl": "https://my.server.com/platform-provider.html"
    },
    "snapshot": {
        ...
    }
}
```

Overriding default behavior in custom HTML

The custom HTML document must call fin.Platform.init() to initialize the platform and open the manifest-defined snapshot.

Minimal custom Provider HTML

<html>
    <head>
        <script>
            fin.Platform.init();
        </script>
    </head>
    <body></body>
</html>

The fin.Platform.init() method takes an options argument which may contain an overrideCallback property. The class that implements default Platform behavior is provided as an argument to this callback, and OpenFin uses the callback's return value to handle Platform functionality.

Using overrideCallback allows you to extend or replace default functionality in order to customize Platform behavior. To implement your own handlers for Platform behavior, extend the provided class and override any methods you'd like to alter.

Example: Overriding default getSnapshot behavior

const saveSnapshotToServer = async (snapshot) => {
    // async code here.
    // Send a snapshot to the server, store it locally somewhere, etc.
}

const overrideCallback = (Provider) => {
    // Extend default behavior
    class MyOverride extends Provider {
        async getSnapshot() {
            // Call super to access vanilla platform behavior
            const snapshot = await super.getSnapshot();
            // Perform any additional logic needed
            const modifiedSnapshot = { ...snapshot, answer: 42 }
            await saveSnapshotToServer(modifiedSnapshot);
            return modifiedSnapshot;
        }
    }
    // Return instance with methods to be consumed by Platform
    return new MyOverride();
};
fin.Platform.init({ overrideCallback });

You can perform any custom initialization before calling fin.Platform.init()

const overrideCallback = async (Provider) => {
    // Do async stuff here
    const userInfo = await loginUser();

    // Extend default behavior
    class MyOverride extends Provider {
        async getSnapshot() {
            const snapshot = await super.getSnapshot();
            return { ...snapshot, userInfo };
        }
    }
    // Return instance with methods to be consumed by Platform
    return new MyOverride();
};
fin.Platform.init({ overrideCallback });

Did this page help you?