The Platform Component Registry
Platform Components are bundled into "packages". A package is a JavaScript bundle that registers components when it loads.
Platform Components are registered and loaded using package and component names - for example:
import { componentLoader, ComponentDefinition } from '@skedulo/horizon-core'
const component: ComponentDefinition = ...
componentLoader.registerComponent('listviews-package', 'DataTable', component)
const loadingState = componentLoader.loadComponent(apiClient, 'listviews-package', 'DataTable')
// loadingState.state is `loading`, `error`, or `loaded`
When a component is requested (using componentLoader.loadComponent) the package is asynchronously loaded (if it has not been loaded yet). The available packages are currently hard-coded - in future this will be dynamic, versioned, and will come from a backend registry. Once the package has run its components will have been registered and can be returned from the registry.
The framework-specific Platform Component loaders should be used instead of using componentLoader.loadComponent directly:
// React
import { PlatformComponent } from '@skedulo/horizon-core'
const PlatformHost = () => (
<PlatformComponent packageName="listviews-package" name="DataTable" />
)
Any properties passed to the Platform Component loader are passed to the component - this means you could, for example, have a DataLoader component and pass a resourceId for it to load.
Registering Components for Page Builder
Components can be made available in the Page Builder by providing metadata when registering them. Components with metadata are discoverable and configurable within the Page Builder interface.
import { componentLoader, ComponentDefinition, ComponentMetadata } from '@skedulo/horizon-core'
const component: ComponentDefinition = ...
const metadata: ComponentMetadata = {
name: 'Data Table',
description: 'A configurable data table component for displaying records',
version: '1.0.0',
properties: {
resourceType: {
type: 'string',
description: 'The type of resource to display',
required: true
},
pageSize: {
type: 'number',
description: 'Number of records per page',
default: 20
}
},
propertiesEditor: {
component: 'DataTablePropertyEditor',
package: 'admin-components'
}
}
componentLoader.registerComponent('listviews-package', 'DataTable', component, metadata)
ComponentMetadata Properties
| Property | Type | Description |
|---|---|---|
name | string | Display name for the component in Page Builder |
description | string | Description of what the component does |
version | string? | Component version (optional) |
properties | Record<string, unknown>? | Schema defining configurable properties (optional) |
propertiesEditor | object? | Custom property editor configuration (optional) |
Custom Property Editors
For components that need advanced configuration, you can specify a custom property editor:
const metadata: ComponentMetadata = {
name: 'Advanced Chart',
description: 'A customizable chart component',
propertiesEditor: {
component: 'ChartPropertyEditor', // Component name for the custom editor
package: 'chart-components', // Package containing the editor (optional)
},
}
If no package is specified for the properties editor, it will be assumed to be in the same package as the component being configured.
Discovering Available Components
Components registered with metadata can be discovered using the component loader:
import { componentLoader } from '@skedulo/horizon-core'
// Get all components with metadata (available in Page Builder)
const availableComponents = componentLoader
.listComponents()
.filter((component) => component.metadata) // Only components with metadata
console.log(availableComponents)
// [
// {
// package: 'listviews-package',
// component: 'DataTable',
// metadata: { name: 'Data Table', description: '...', ... }
// }
// ]