You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

61 lines
1.4 KiB

import { type Component, markRaw } from 'vue'
export type WidgetSide = 'left' | 'right' | 'bottom'
export interface WidgetOption {
name: string
title?: string
icon: Component
shortcut?: string
side: WidgetSide
component: Component
order?: number
}
const _widgetMap = new Map<string, WidgetOption>()
export class WidgetInfo {
option: WidgetOption
constructor(option: WidgetOption) {
this.option = option
}
public install() {
if (!this.option.name) {
throw new Error('Widget name is required')
}
if (!this.option.component) {
throw new Error('Widget component is required')
}
if (_widgetMap.has(this.option.name)) {
console.log(`Widget ${this.option.name} already exists`)
return
}
_widgetMap.set(this.option.name, this.option)
}
}
/**
* 根据 Widget 定义的位置获取 Widget, 并按 order 排序
*/
export function getWidgetBySide(side: WidgetSide): WidgetOption[] {
return Array.from(_widgetMap.values())
.filter((widget) => widget.side === side)
.sort((a, b) => (a.order || 0) - (b.order || 0))
}
export function getWidgetByName(name: string): WidgetOption | undefined {
return _widgetMap.get(name)
}
export function getAllWidget(): WidgetOption[] {
return Array.from(_widgetMap.values()).sort((a, b) => (a.order || 0) - (b.order || 0))
}
/**
* 定义一个 Widget
*/
export function defineWidget(option: WidgetOption): WidgetInfo {
return new WidgetInfo(option)
}