Declaring a Panel
This page is for people building on OpenX. Every panel in the workspace is declared once and registered with the workspace's panel registry. The workspace draws whatever the registry holds, so a panel you add appears, docks, closes and comes back like the built-in ones.
The declaration
A panel's declaration (PanelDeclaration, exported from @o-industrial/common/atomic/dock) holds:
| Field | What it is |
|---|---|
Id | The panel's stable id. It is kept in saved layouts, so it never changes once shipped. |
Title | The name a person reads in the panel's title bar and in menus. |
Render | Draws the panel's content. |
DrawsOwnHeader | true when the content draws its own title bar; otherwise the workspace draws one. |
MinimumSize | The smallest width and height the panel may be resized to, in pixels. |
DefaultPlacement | Where it starts in the Default layout: the side, its order there, and its starting size. |
FloatingSize | The size a floating copy of the panel opens at. |
Collapse | What collapsing does: pause keeps its state and stops its live work; unmount lets it go. |
EmptyState | What the panel says when it has nothing to show. See below. |
RestorePath | How a person brings the panel back after closing it, in words. |
Two panels with the same Id are refused when the second one is registered.
The engine under the dock
The dock is drawn by dockview-core, the free core of the open-source dockview library, pinned to
one exact version. It loads only in the browser, after the page arrives: until it does, the page
draws a plain version of the same layout. The drag feel, the Move to menu, the layout tree and the
panel registry are OpenX's own, built on top of it in @o-industrial/common/atomic/dock. A panel's
declaration never names the engine, so your panel does not change if the engine does.
The empty-state sentence
When a panel has nothing to show, it says what will appear there and how to get it, instead of
sitting blank. You declare this once, in EmptyState:
| Field | What it is |
|---|---|
Sentence | One sentence: what will appear in the panel, and how a person gets it there. |
DocsHref | Optional. A docs page that explains more: an https: link, or a site path that starts with /. |
Action | Optional. One next step, drawn as a button beside the sentence: a Label and a Command to run. |
Write the sentence for someone who has never used the product. Say what the panel will hold and the one thing that fills it, for example: "Nothing is on the canvas yet. Add your first node from the Node Bank."
What the registry refuses
The registry checks the empty state when the panel is registered, and refuses the panel, naming it, when:
- the panel has no sentence at all: no
EmptyState, or anEmptyStatewith noSentence, or aSentencethat is not text. Every panel declares one; there is no exemption; - the sentence is empty or only spaces;
- the docs link is anything other than an
https:link or a site path (ajavascript:or plainhttp:link is refused, and so is a path starting with//); - the action has no label, or names a command the workspace does not run. The workspace tells the
registry which commands it runs when it creates it (
new PanelRegistry({ Commands })).
A refused panel is not registered; the panels around it are not affected.
Drawing it
Your panel decides when it is empty: the Live Stream knows it has received nothing, the
Inspector knows no node is selected. For that case, return PanelEmptyStateNotice. It reads your
panel's declared sentence and draws it the same way every panel does, with a Read more link that
opens your docs page in a new tab, and your action's button.
import { PanelEmptyStateNotice } from '@o-industrial/common/atomic/dock';
if (rows.length === 0) {
return <PanelEmptyStateNotice State={connected ? 'empty' : 'loading'} />;
}
Pass the panel's data state as State:
State | What is drawn |
|---|---|
loading | A loading notice, never the empty sentence. Pass Message for your own words. |
error | An error notice, for data that could not be reached or a dropped connection. |
empty | Your declared sentence, with its link and its button. |
ready | Nothing: the panel has data to show. |
Only say empty once you know the data really is empty, so the sentence never flashes up while the
data is still on its way. A filter that hides every row is not an empty panel: say that in the
panel's own words ("No impulses match the current filters.").
Related
- Panels and Windows
- Panel Controls
- Contributing to Thinky: what an open panel of your kind shares with Thinky (identifiers only, never a secret), and the tools your kind adds.