WIP-0003: Slots Enhancement Specification¶
Introduction¶
Slots are a core mechanism in Whitebox that allows plugins to provide UI components at specific locations within the application. This WIP describes the overall slot architecture and proposes enhancements to make it more flexible.
Slotting¶
To allow plugins to augment the app, we are using a slotting mechanism. Slots are defined by the core app, as well as by plugins.
For example, on the dashboard, we'll have a slot for the map display. The core will,
inside this slot, render the component that a designated plugin with map
capability with map.display
component definition provides. A plugin may technically
provide a map component that is not an actual map, illustrating that the core system
should not make any assumptions about the components provided by plugins.
An example of a slot usage, rendering a map component, within a dashboard:
This will render the component that a plugin with the map
capability provides for display
.
Enhancement Proposal¶
We propose enhancing the SlotLoader component with two new props:
-
required
(default:false)
:- When
true
: Displays an error when component not found - When
false
: No error displayed if component not found, renders nothing instead
- When
-
collection
(default:false)
:- When
true
: Renders all matching components for the slot - When
false
: Renders only the first matching component
- When
Usage¶
// Required slot (shows error if not found)
<SlotLoader name="map.unknown" required />
// Collection slot (shows all matching components)
<SlotLoader name="map.display" collection />
// Both optional (default) and not a collection (default)
// This will not show an error if the component is not found
// And will only show the first matching component
<SlotLoader name="sidebar.widget" />
Example¶
For example, slot C1 to C5 would be implemented as follows:
const MapArea = () => {
return (
<div className="c_map_area w-dvw h-full">
// C1
<SlotLoader name="map.display" required />
// C2
<div className="absolute top-0 left-0">
<SlotLoader name="flight.overlay.info" required />
</div>
// C3
<div className="absolute bottom-0 left-0">
<SlotLoader name="devices.overlay.list" collection />
</div>
// C4
<div className="absolute bottom-0 right-0">
<SlotLoader name="flight.overlay.notification" />
</div>
// C5
<div className="absolute top-0 right-0">
<SlotLoader name="flight.overlay.action" required />
</div>
</div>
)
}
Plugin Changes¶
For exporting multiple components for the same slot, plugins would need to add a suffix to the slot name in the slot_component_map
to differentiate themselves. For example:
Plugin A:
Plugin B:
slot_component_map = {
"map.display.extras_1": "whitebox_plugin_gps_display_extras/MapExtras1",
"map.display.extras_xyz": "whitebox_plugin_gps_display_extras/MapExtrasXYZ",
}
SlotLoader will search for all components matching pattern map.display.*
and render them in a list format. This allows for multiple plugins to provide components for the same slot without conflicts.