Feat v0.2.3 sdk tasks (#7)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #7.
This commit is contained in:
77
src/js/sw/sdk/slots.js
Normal file
77
src/js/sw/sdk/slots.js
Normal file
@@ -0,0 +1,77 @@
|
||||
// ==========================================
|
||||
// Switchboard Core — SDK: Slot System
|
||||
// ==========================================
|
||||
// Named shell regions where extensions inject UI.
|
||||
//
|
||||
// Factory: createSlots(emitFn)
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* Create the slot registry.
|
||||
*
|
||||
* @param {Function} emitFn — events.emit for change notifications
|
||||
* @returns {object} slots
|
||||
*/
|
||||
export function createSlots(emitFn) {
|
||||
/** @type {Map<string, Array<{id:string, component:Function, priority:number}>>} */
|
||||
const _registry = new Map();
|
||||
|
||||
function _sort(arr) {
|
||||
arr.sort((a, b) => a.priority - b.priority);
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Register a component into a named slot.
|
||||
* @param {string} name — slot name (e.g. 'toolbar', 'statusbar')
|
||||
* @param {object} entry — { id, component, priority? }
|
||||
* @returns {Function} unregister
|
||||
*/
|
||||
register(name, { id, component, priority = 100 }) {
|
||||
if (!_registry.has(name)) _registry.set(name, []);
|
||||
const list = _registry.get(name);
|
||||
|
||||
// Prevent duplicate ids in same slot
|
||||
const idx = list.findIndex(e => e.id === id);
|
||||
if (idx !== -1) list.splice(idx, 1);
|
||||
|
||||
list.push({ id, component, priority });
|
||||
_sort(list);
|
||||
|
||||
emitFn('slots.changed', { slot: name, action: 'register', id }, { localOnly: true });
|
||||
|
||||
return () => this.unregister(name, id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a component from a slot.
|
||||
*/
|
||||
unregister(name, id) {
|
||||
const list = _registry.get(name);
|
||||
if (!list) return;
|
||||
const idx = list.findIndex(e => e.id === id);
|
||||
if (idx !== -1) {
|
||||
list.splice(idx, 1);
|
||||
if (list.length === 0) _registry.delete(name);
|
||||
emitFn('slots.changed', { slot: name, action: 'unregister', id }, { localOnly: true });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get sorted entries for a slot.
|
||||
* @param {string} name
|
||||
* @returns {Array<{id:string, component:Function, priority:number}>}
|
||||
*/
|
||||
get(name) {
|
||||
return _registry.get(name) || [];
|
||||
},
|
||||
|
||||
/**
|
||||
* List all slot names that have content.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
names() {
|
||||
return [..._registry.keys()];
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user