Skip to main content

Dock 3

info

Dock 3 represents a fundamental architectural shift from Dock 2 and Dock 1. Although Dock 3 includes all of the functionality of its predecessors, it is not backwards compatible. You must create Dock 3 as a separate entity from Dock 1 and Dock 2.

The Dock component of HERE Core UI gives users a single point of access to favorites, contents, and workspaces, as well as other HERE Core UI components. It streamlines user's workflows and enhances their overall user experience.

Dock 3 introduces a per-platform architecture where each HERE Core UI platform owns its dedicated dock instance. You add Dock and control which components it includes with the @openfin/workspace-platform Dock API.

Components

HERE Core Dock 3

Drag handle

When users first open the browser, Dock appears at the bottom of their screen. Users can drag it around to place it where they want. The Dock location is saved for users when they restart the browser. If users again move it, the new location is saved.

This is the platform's logo, typically your organization's logo. By default, a HERE logo is used.

Workspace menu

The workspace menu enables users to save, rename, switch, and delete workspaces.

Content menu and panel

The integrated content panel allows users to browse and discover content directly from Dock; desktop applications are denoted with arrows on the bottom right of the application's icon. You create the base content directory for users and specify the content items in the base directory and nested subdirectories. Dock automatically merges folders with the same name and removes duplicates to keep content tidy and easy to navigate. Dock 3 addresses previous limitations while establishing patterns for future HERE Core UI components.

Favorites

As a platform developer, you can define "favorites" that appear in the Dock by default. If you choose, users can add their own favorites by clicking a star next to items in the content panel. They can also remove favorited items from the Dock; you can configure whether the Dock saves these changes. Dock 3 is purely visual — it doesn’t store or sync anything. Your platform decides what to display and how to handle actions. You can treat these items as bookmarks, favorites, or use your own terms entirely.

New architecture

Dock 3.0 represents a transformation of the Dock component from a singleton (shared by all platforms) to a per-platform design. Each HERE Core UI platform owns a dedicated Dock instance.

This approach avoids cross-platform conflicts and simplifies versioning. The Dock version is tied to the platform version for predictable compatibility. Platforms control their own Dock configuration, storage, and behavior. The approach supports multiple platform versions running side by side, for different platforms.

Package integration

The Dock 3 API is built directly into @openfin/workspace-platform package, which means that it is co-versioned with workspace-platform releases. This approach enables predictable deployment patterns without version compatibility issues, and reduces overall platform deployment footprint

Child window architecture

The Dock 3 window operates as child window of a HERE Core UI platform, which provides clear parent-child relationships for simplified window management. It also inherits platform context (theme, security, runtime settings).

Event-driven architecture

Dock 3 supports fully asynchronous event processing and complex operations (authentication, data fetching, cross-service communication).

Comparison with previous architectures

AspectDock 1/2Dock 3
API@openfin/workspace dock module@openfin/workspace-platform
Deployment modelSingleton servicePer-platform component
VersioningIndependent versioningCo-versioned with platform
Code sharingSeparate implementationsShared core with specialized entry points
CustomizationConfiguration flagsOverride patterns and context injection
StorageFixed local storagePluggable storage abstraction
Event modelBasic callbacksComprehensive event system
Platform integrationExternal serviceChild window component

Basic initialization

Initialize Dock 3 using a declarative configuration. The process requires a default configuration object, optional override callback for behavior customization, and window options for positioning.

import { Dock } from '@openfin/workspace-platform';

// Initialize dock with comprehensive configuration
const dockProvider = await Dock.init({
// Default configuration defines the dock's initial state and content
defaultConfig: {
// Platform identification displayed in dock title bar and taskbar
title: "My Platform Dock",
icon: "https://example.com/platform-icon.png",

// Favorites appear as shortcuts in the main dock bar for quick access
favorites: [
{
id: "calculator", // Unique identifier for event handling
icon: "https://example.com/calc-icon.png", // Visual representation in dock bar
tooltip: "Calculator App", // Hover text for user guidance
action: "launch-calculator" // Custom action identifier for launch handling
}
],

// Content menu provides hierarchical organization for complex app portfolios
contentMenu: [
{
id: "tools", // Unique folder identifier
label: "Tools", // Display name in content menu
icon: "https://example.com/tools-icon.png", // Folder icon for visual organization
children: [ // Nested items within this folder
{
id: "notepad", // Unique item identifier
label: "Notepad", // Display name for menu item
icon: "https://example.com/notepad-icon.png", // Item-specific icon
action: "launch-notepad" // Action identifier for launch handling
}
]
}
]
},

// Override callback provides customization points for dock behavior
override: (Base) => class MyDockProvider extends Base {
// Handle all launch events from favorites and content menu interactions
async launchEntry(payload) {
console.log('Launching dock entry:', payload);
// Payload contains: { id, action, source, bounds }
// Implement your platform-specific launch logic here
// Examples: open applications, navigate to views, trigger workflows
}
},

// Window options control dock positioning and display behavior
windowOptions: {
defaultCentered: true, // Center dock on initial display
includeInSnapshots: true // Include dock in workspace snapshots for persistence
}
});

Configuration options

Dock 3's configuration uses the Dock3Config interface for content settings, and the types DockInitOptions for initialization and DockAllowedWindowOptions for window properties.

UI configuration options

You can configure aspects of the Dock UI. Note that "bookmarking" refers to the "star" next to content panel items; it is not a general-purpose bookmarking feature. See Bookmark events for handling when the user clicks a star icon.

uiConfig: {
contentMenu: {
// Show star icons for bookmarking
enableBookmarking: true
},
// Show/hide drag handle
hideDragHandle: false,
// Make provider icon a dropdown button
providerIconContentMenu: true,
moreMenu: {
quitPlatform: {
// Show platform name in quit button
hidePlatformTitle: false,
// Show confirmation dialog
skipDialog: false
}
}
}

Content structure

Dock 3 provides two mechanisms for users to access content:

  • Favorites: Quick access shortcuts for frequently used tools

  • Content directory: Hierarchical system for comprehensive application portfolios

Favorites

Favorites appear as shortcuts in the main dock bar.

favorites: [
{
id: "my-app", // Unique identifier used in events and programmatic updates
icon: "https://example.com/app-icon.png", // Icon URL displayed in dock bar (supports theme-specific variants)
tooltip: "My Application", // Hover text providing user context and guidance
action: "launch-app", // Custom action string passed to launchEntry() handler
disabled: false, // Controls interactivity - disabled items appear grayed out
sortOrder: 1 // Numeric position in dock bar (lower numbers appear first)
}
]

Content directory

The content directory supports hierarchical menu structures.

contentMenu: [
{
id: "productivity", // Unique folder identifier for programmatic access and events
label: "Productivity", // Display name shown in content menu dropdown
icon: "https://example.com/productivity-icon.png", // Folder icon (optional, helps visual organization)
children: [ // Nested items - unlimited depth supported
{
id: "documents", // Sub-folder identifier for nested organization
label: "Documents", // Display name for this sub-category
children: [ // Further nesting demonstrates hierarchical structure
{
id: "word-processor", // Unique item identifier for launch events
label: "Word Processor", // User-facing name displayed in menu
icon: "https://example.com/word-icon.png", // Item-specific icon for visual identification
action: "launch-word" // Action string passed to launchEntry() when clicked
}
]
}
]
}
]

Event handling

Launch events

// Override callback provides extension points for customizing dock behavior
override: (Base) => class MyDockProvider extends Base {
// Handle all launch events from favorites clicks and content menu selections
async launchEntry(payload) {
// Destructure common payload properties for easier access
const { id, action } = payload;
// Full payload also includes: source, bounds, timestamp, metadata
// Route different actions to appropriate platform-specific implementations
switch (action) {
case 'launch-calculator':
// Handle calculator app launch - could open native app, web view, or platform component
await this.openCalculator();
break;
case 'launch-notepad':
// Handle notepad launch - implement your platform's text editing solution
await this.openNotepad();
break;
default:
// Handle unknown actions gracefully - log for debugging or show user feedback
console.warn(`Unknown dock action: ${action} for item: ${id}`);
// Consider implementing fallback behavior or user notification
}
}
}

Bookmark events

// Handle bookmark toggle events when users click star icons in content menu
async bookmarkContentMenuEntry(payload) {
// Extract bookmark state and item identifier from event payload
const { id, bookmarked } = payload;
// Full payload also includes: label, icon, source, bounds, parentId, path

if (bookmarked) {
// User clicked to bookmark/favorite this item - add to user's saved items
await this.addToBookmarks(id);
// Consider: sync to cloud storage, update user preferences, show confirmation
} else {
// User clicked to remove bookmark - remove from saved items collection
await this.removeFromBookmarks(id);
// Consider: update UI state, sync removal to backend, provide undo option
}

// Note: The dock UI automatically updates the star icon state
// Your implementation handles the business logic and data persistence
}

Asynchronous event handling

The event system supports fully asynchronous processing, allowing platforms to perform complex operations without blocking the dock UI.

override: (Base) => class MyDockProvider extends Base {
async launchEntry(payload) {
// Complex async operations won't block dock UI
const authResult = await this.authenticateUser();
const permissions = await this.checkPermissions(payload.id);
const appConfig = await this.loadAppConfiguration(payload.action);

if (authResult.success && permissions.allowed) {
await this.launchApplication(appConfig);
}
}
}

Event coordination and sequencing

The event system provides sequencing information that enables platforms to coordinate complex multi-step operations.

override: (Base) => class MyDockProvider extends Base {
private eventQueue = new Map();

async handleEvent(payload) {
// Use timestamp for operation sequencing
const sequence = payload.timestamp;

// Coordinate with other platform operations
if (this.isWorkspaceOperation(payload)) {
await this.waitForPendingOperations();
}

// Process with guaranteed ordering
await this.processInSequence(payload, sequence);
}
}

Contextual information for UI overlays

Event payloads include precise spatial information that enables sophisticated UI overlay features.

async launchEntry(payload) {
const { bounds } = payload;

// Show loading indicator at exact click location
this.showLoadingOverlay({
x: bounds.element.x + bounds.element.width / 2,
y: bounds.element.y + bounds.element.height,
relativeTo: bounds.dock
});

await this.performLaunch(payload);
this.hideLoadingOverlay();
}

Hierarchical context tracking

Content directory events provide complete hierarchical context for implementing breadcrumb navigation and deep-linking.

async contentMenuItemClicked(payload) {
if (payload.path) {
// Update platform navigation state with full path
this.updateBreadcrumbs(payload.path);
this.recordNavigationAnalytics({
depth: payload.path.length,
category: payload.path[0],
finalItem: payload.id
});
}
}

Managing Dock at runtime

Dock 3 supports control over behavior of the Dock throughout the application lifecycle. You can dynamically update the configuration and window positioning. You can also manage the lifecycle to start and shut down the Dock as needed.

Updating configuration

// Get reference to the current dock provider instance for this platform
const dockProvider = Dock.getCurrentProviderSync();
// Note: This is synchronous - dock must already be initialized via Dock.init()

// Update dock configuration by merging new data with existing config
await dockProvider.updateConfig({
...dockProvider.config, // Spread existing configuration to preserve all settings
favorites: [ // Replace favorites array with updated version
...dockProvider.config.favorites, // Keep all existing favorites in their current positions
newFavorite // Append new favorite to end of favorites list
]
});
// This triggers UI re-render and optionally saves to storage depending on saveConfig() implementation
// Consider: validation of newFavorite structure, duplicate checking, sort order management

Window control


// Get dock window
const dockWindow = dockProvider.getWindowSync();

// Center the dock
await dockWindow.center();

// Move to specific position
await dockWindow.moveTo(100, 100);

Lifecycle management


// Wait for dock to be ready
await dockProvider.ready;

// Shutdown dock
await dockProvider.shutdown();

Theme support

Dock 3 is integrated with the HERE Core UI theming system. It automatically inherits the platform theme, with dock-specific overrides if desired.

Theme-aware icons

// Single icon
icon: "https://example.com/icon.png"

// Theme-specific icons
icon: {
light: "https://example.com/icon-light.png",
dark: "https://example.com/icon-dark.png"
}

Default behavior

By default, dock configuration is saved to local storage and persists between sessions.

Custom storage

Override storage methods to use your own persistence layer:

override: (Base) => class MyDockProvider extends Base {
async saveConfig({ config }) {
// Save to your custom storage
await myStorage.saveDockConfig(config);
}

async loadConfig() {
// Load from your custom storage
const savedConfig = await myStorage.getDockConfig();
if (savedConfig) {
this.config = savedConfig;
}
return this.config;
}
}

Disable configuration persistence

async loadConfig() {
// Always return default config (no persistence)
return this.config;
}