@aipanel/ui 1.2.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/AI-panel-widget/composables/use-inspector.d.ts +52 -0
- package/es/AI-panel-widget/composables/use-inspector.mjs +437 -0
- package/es/AI-panel-widget/composables/use-persist-state.d.ts +32 -0
- package/es/AI-panel-widget/composables/use-persist-state.mjs +83 -0
- package/es/AI-panel-widget/composables/use-selection.d.ts +19 -0
- package/es/AI-panel-widget/composables/use-selection.mjs +112 -0
- package/es/AI-panel-widget/composables/use-session.d.ts +16 -0
- package/es/AI-panel-widget/composables/use-session.mjs +47 -0
- package/es/AI-panel-widget/composables/use-split.d.ts +30 -0
- package/es/AI-panel-widget/composables/use-split.mjs +133 -0
- package/es/AI-panel-widget/composables/use-widget.d.ts +27 -0
- package/es/AI-panel-widget/composables/use-widget.mjs +78 -0
- package/es/AI-panel-widget/index.d.ts +5 -0
- package/es/AI-panel-widget/index.mjs +9 -0
- package/es/AI-panel-widget/src/assets/logo.svg +13 -0
- package/es/AI-panel-widget/src/components/AIPanelLogo-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/AIPanelLogo.vue.d.ts +8 -0
- package/es/AI-panel-widget/src/components/AIPanelLogo.vue.mjs +40 -0
- package/es/AI-panel-widget/src/components/ChatPanel-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/ChatPanel.vue.d.ts +179 -0
- package/es/AI-panel-widget/src/components/ChatPanel.vue.mjs +308 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +44 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.mjs +311 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/index.d.ts +3 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/index.mjs +5 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/types.d.ts +24 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/types.mjs +0 -0
- package/es/AI-panel-widget/src/components/Frame-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/Frame.vue.d.ts +22 -0
- package/es/AI-panel-widget/src/components/Frame.vue.mjs +143 -0
- package/es/AI-panel-widget/src/components/Header-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/Header.vue.d.ts +27 -0
- package/es/AI-panel-widget/src/components/Header.vue.mjs +683 -0
- package/es/AI-panel-widget/src/components/ResizeHandle-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/ResizeHandle.vue.d.ts +22 -0
- package/es/AI-panel-widget/src/components/ResizeHandle.vue.mjs +79 -0
- package/es/AI-panel-widget/src/components/SelectHint-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SelectHint.vue.d.ts +3 -0
- package/es/AI-panel-widget/src/components/SelectHint.vue.mjs +40 -0
- package/es/AI-panel-widget/src/components/SelectedBubbles-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SelectedBubbles.vue.d.ts +3 -0
- package/es/AI-panel-widget/src/components/SelectedBubbles.vue.mjs +84 -0
- package/es/AI-panel-widget/src/components/SelectedNodes-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SelectedNodes.vue.d.ts +3 -0
- package/es/AI-panel-widget/src/components/SelectedNodes.vue.mjs +103 -0
- package/es/AI-panel-widget/src/components/SessionList-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SessionList.vue.d.ts +13 -0
- package/es/AI-panel-widget/src/components/SessionList.vue.mjs +222 -0
- package/es/AI-panel-widget/src/components/SplitTrigger-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SplitTrigger.vue.d.ts +18 -0
- package/es/AI-panel-widget/src/components/SplitTrigger.vue.mjs +112 -0
- package/es/AI-panel-widget/src/components/Trigger-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/Trigger.vue.d.ts +28 -0
- package/es/AI-panel-widget/src/components/Trigger.vue.mjs +74 -0
- package/es/AI-panel-widget/src/context.d.ts +67 -0
- package/es/AI-panel-widget/src/context.mjs +16 -0
- package/es/AI-panel-widget/src/index-sfc.css +1 -0
- package/es/AI-panel-widget/src/index.vue.d.ts +69 -0
- package/es/AI-panel-widget/src/index.vue.mjs +782 -0
- package/es/AI-panel-widget/src/types.d.ts +2 -0
- package/es/AI-panel-widget/src/types.mjs +0 -0
- package/es/AI-panel-widget/style/index-pure.d.ts +0 -0
- package/es/AI-panel-widget/style/index-pure.mjs +0 -0
- package/es/AI-panel-widget/style/index.d.ts +0 -0
- package/es/AI-panel-widget/style/index.mjs +0 -0
- package/es/AI-panel-widget/style/less-pure.d.ts +0 -0
- package/es/AI-panel-widget/style/less-pure.mjs +0 -0
- package/es/AI-panel-widget/style/less.d.ts +0 -0
- package/es/AI-panel-widget/style/less.mjs +0 -0
- package/es/env.d.ts +15 -0
- package/es/index.d.ts +7 -0
- package/es/index.mjs +22 -0
- package/es/setup.d.ts +1 -0
- package/es/setup.mjs +4 -0
- package/lib/AI-panel-widget/composables/use-inspector.cjs +466 -0
- package/lib/AI-panel-widget/composables/use-inspector.d.ts +52 -0
- package/lib/AI-panel-widget/composables/use-persist-state.cjs +102 -0
- package/lib/AI-panel-widget/composables/use-persist-state.d.ts +32 -0
- package/lib/AI-panel-widget/composables/use-selection.cjs +131 -0
- package/lib/AI-panel-widget/composables/use-selection.d.ts +19 -0
- package/lib/AI-panel-widget/composables/use-session.cjs +66 -0
- package/lib/AI-panel-widget/composables/use-session.d.ts +16 -0
- package/lib/AI-panel-widget/composables/use-split.cjs +152 -0
- package/lib/AI-panel-widget/composables/use-split.d.ts +30 -0
- package/lib/AI-panel-widget/composables/use-widget.cjs +97 -0
- package/lib/AI-panel-widget/composables/use-widget.d.ts +27 -0
- package/lib/AI-panel-widget/index.cjs +39 -0
- package/lib/AI-panel-widget/index.d.ts +5 -0
- package/lib/AI-panel-widget/src/assets/logo.svg +13 -0
- package/lib/AI-panel-widget/src/components/AIPanelLogo-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/AIPanelLogo.vue.cjs +69 -0
- package/lib/AI-panel-widget/src/components/AIPanelLogo.vue.d.ts +8 -0
- package/lib/AI-panel-widget/src/components/ChatPanel-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/ChatPanel.vue.cjs +337 -0
- package/lib/AI-panel-widget/src/components/ChatPanel.vue.d.ts +179 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.cjs +330 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +44 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/index.cjs +35 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/index.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/types.cjs +15 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/types.d.ts +24 -0
- package/lib/AI-panel-widget/src/components/Frame-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/Frame.vue.cjs +162 -0
- package/lib/AI-panel-widget/src/components/Frame.vue.d.ts +22 -0
- package/lib/AI-panel-widget/src/components/Header-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/Header.vue.cjs +702 -0
- package/lib/AI-panel-widget/src/components/Header.vue.d.ts +27 -0
- package/lib/AI-panel-widget/src/components/ResizeHandle-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/ResizeHandle.vue.cjs +98 -0
- package/lib/AI-panel-widget/src/components/ResizeHandle.vue.d.ts +22 -0
- package/lib/AI-panel-widget/src/components/SelectHint-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SelectHint.vue.cjs +59 -0
- package/lib/AI-panel-widget/src/components/SelectHint.vue.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/SelectedBubbles-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SelectedBubbles.vue.cjs +103 -0
- package/lib/AI-panel-widget/src/components/SelectedBubbles.vue.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/SelectedNodes-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SelectedNodes.vue.cjs +122 -0
- package/lib/AI-panel-widget/src/components/SelectedNodes.vue.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/SessionList-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SessionList.vue.cjs +241 -0
- package/lib/AI-panel-widget/src/components/SessionList.vue.d.ts +13 -0
- package/lib/AI-panel-widget/src/components/SplitTrigger-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SplitTrigger.vue.cjs +131 -0
- package/lib/AI-panel-widget/src/components/SplitTrigger.vue.d.ts +18 -0
- package/lib/AI-panel-widget/src/components/Trigger-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/Trigger.vue.cjs +103 -0
- package/lib/AI-panel-widget/src/components/Trigger.vue.d.ts +28 -0
- package/lib/AI-panel-widget/src/context.cjs +35 -0
- package/lib/AI-panel-widget/src/context.d.ts +67 -0
- package/lib/AI-panel-widget/src/index-sfc.css +1 -0
- package/lib/AI-panel-widget/src/index.vue.cjs +811 -0
- package/lib/AI-panel-widget/src/index.vue.d.ts +69 -0
- package/lib/AI-panel-widget/src/types.cjs +15 -0
- package/lib/AI-panel-widget/src/types.d.ts +2 -0
- package/lib/AI-panel-widget/style/index-pure.cjs +0 -0
- package/lib/AI-panel-widget/style/index-pure.d.ts +0 -0
- package/lib/AI-panel-widget/style/index.cjs +0 -0
- package/lib/AI-panel-widget/style/index.d.ts +0 -0
- package/lib/AI-panel-widget/style/less-pure.cjs +0 -0
- package/lib/AI-panel-widget/style/less-pure.d.ts +0 -0
- package/lib/AI-panel-widget/style/less.cjs +0 -0
- package/lib/AI-panel-widget/style/less.d.ts +0 -0
- package/lib/env.d.ts +15 -0
- package/lib/index.cjs +42 -0
- package/lib/index.css +0 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.less +0 -0
- package/lib/setup.cjs +23 -0
- package/lib/setup.d.ts +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var use_persist_state_exports = {};
|
|
19
|
+
__export(use_persist_state_exports, {
|
|
20
|
+
usePersistState: () => usePersistState
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(use_persist_state_exports);
|
|
23
|
+
var import_vue = require("vue");
|
|
24
|
+
var import_core = require("@aipanel/core");
|
|
25
|
+
const log = (0, import_core.createLogger)("AIPanelWidget");
|
|
26
|
+
const STORAGE_KEY = "aipanel-widget-state";
|
|
27
|
+
function loadState() {
|
|
28
|
+
if (typeof window === "undefined") return null;
|
|
29
|
+
try {
|
|
30
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
31
|
+
if (stored) {
|
|
32
|
+
return JSON.parse(stored);
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
log.error("Failed to load persisted state:", { error: e });
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
function saveState(state) {
|
|
40
|
+
if (typeof window === "undefined") return;
|
|
41
|
+
try {
|
|
42
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
|
|
43
|
+
} catch (e) {
|
|
44
|
+
log.error("Failed to save state:", { error: e });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function usePersistState(options) {
|
|
48
|
+
const restoreState = () => {
|
|
49
|
+
const saved = loadState();
|
|
50
|
+
if (options.onRestore) {
|
|
51
|
+
options.onRestore(saved || {});
|
|
52
|
+
}
|
|
53
|
+
return saved;
|
|
54
|
+
};
|
|
55
|
+
const getCurrentState = () => ({
|
|
56
|
+
open: options.open.value,
|
|
57
|
+
minimized: options.minimized.value,
|
|
58
|
+
promptDockVisible: options.promptDockVisible.value,
|
|
59
|
+
reviewPanelVisible: options.reviewPanelVisible.value,
|
|
60
|
+
bubbleOffset: options.bubbleOffset.value,
|
|
61
|
+
theme: options.theme.value,
|
|
62
|
+
sessionListCollapsed: options.sessionListCollapsed.value,
|
|
63
|
+
splitPanelWidth: options.splitPanelWidth?.value,
|
|
64
|
+
displayMode: options.displayMode?.value,
|
|
65
|
+
splitPosition: options.splitPosition?.value
|
|
66
|
+
});
|
|
67
|
+
const persistState = () => {
|
|
68
|
+
saveState(getCurrentState());
|
|
69
|
+
};
|
|
70
|
+
const watchers = [
|
|
71
|
+
options.open,
|
|
72
|
+
options.minimized,
|
|
73
|
+
options.promptDockVisible,
|
|
74
|
+
options.reviewPanelVisible,
|
|
75
|
+
options.bubbleOffset,
|
|
76
|
+
options.theme,
|
|
77
|
+
options.sessionListCollapsed
|
|
78
|
+
];
|
|
79
|
+
if (options.splitPanelWidth) {
|
|
80
|
+
watchers.push(options.splitPanelWidth);
|
|
81
|
+
}
|
|
82
|
+
if (options.displayMode) {
|
|
83
|
+
watchers.push(options.displayMode);
|
|
84
|
+
}
|
|
85
|
+
if (options.splitPosition) {
|
|
86
|
+
watchers.push(options.splitPosition);
|
|
87
|
+
}
|
|
88
|
+
(0, import_vue.onMounted)(() => {
|
|
89
|
+
restoreState();
|
|
90
|
+
(0, import_vue.watch)(
|
|
91
|
+
watchers,
|
|
92
|
+
() => {
|
|
93
|
+
persistState();
|
|
94
|
+
},
|
|
95
|
+
{ deep: true }
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
return {
|
|
99
|
+
restoreState,
|
|
100
|
+
persistState
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { FloatingBubbleOffset } from "../src/components/FloatingBubble/types";
|
|
3
|
+
import type { AIPanelWidgetTheme, DisplayMode } from "../src/types";
|
|
4
|
+
export interface WidgetPersistState {
|
|
5
|
+
open: boolean;
|
|
6
|
+
minimized: boolean;
|
|
7
|
+
promptDockVisible: boolean;
|
|
8
|
+
reviewPanelVisible: boolean;
|
|
9
|
+
bubbleOffset?: FloatingBubbleOffset;
|
|
10
|
+
theme: AIPanelWidgetTheme;
|
|
11
|
+
sessionListCollapsed: boolean;
|
|
12
|
+
splitPanelWidth?: number;
|
|
13
|
+
displayMode?: DisplayMode;
|
|
14
|
+
splitPosition?: "left" | "right";
|
|
15
|
+
}
|
|
16
|
+
export interface UsePersistStateOptions {
|
|
17
|
+
open: Ref<boolean>;
|
|
18
|
+
minimized: Ref<boolean>;
|
|
19
|
+
promptDockVisible: Ref<boolean>;
|
|
20
|
+
reviewPanelVisible: Ref<boolean>;
|
|
21
|
+
bubbleOffset: Ref<FloatingBubbleOffset | undefined>;
|
|
22
|
+
theme: Ref<AIPanelWidgetTheme>;
|
|
23
|
+
sessionListCollapsed: Ref<boolean>;
|
|
24
|
+
splitPanelWidth?: Ref<number>;
|
|
25
|
+
displayMode?: Ref<DisplayMode>;
|
|
26
|
+
splitPosition?: Ref<"left" | "right">;
|
|
27
|
+
onRestore?: (state: Partial<WidgetPersistState>) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare function usePersistState(options: UsePersistStateOptions): {
|
|
30
|
+
restoreState: () => Partial<WidgetPersistState> | null;
|
|
31
|
+
persistState: () => void;
|
|
32
|
+
};
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var use_selection_exports = {};
|
|
19
|
+
__export(use_selection_exports, {
|
|
20
|
+
useSelection: () => useSelection
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(use_selection_exports);
|
|
23
|
+
var import_vue = require("vue");
|
|
24
|
+
var import_core = require("@aipanel/core");
|
|
25
|
+
function getElementKey(element, index) {
|
|
26
|
+
if (element.filePath && element.line) {
|
|
27
|
+
return `${element.filePath}:${element.line}:${element.column ?? 0}`;
|
|
28
|
+
}
|
|
29
|
+
return `${element.description}-${index}`;
|
|
30
|
+
}
|
|
31
|
+
function getBubbleFileText(element) {
|
|
32
|
+
const fileName = element.filePath?.split("/").pop() || "";
|
|
33
|
+
const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
|
|
34
|
+
return `${fileName}${lineInfo}`;
|
|
35
|
+
}
|
|
36
|
+
function getPanelFileText(element) {
|
|
37
|
+
const fileName = element.filePath?.split("/").pop() || "\u672A\u77E5\u6587\u4EF6";
|
|
38
|
+
const lineInfo = element.line ? `:${element.line}${element.column ? `:${element.column}` : ""}` : "";
|
|
39
|
+
const textPreview = element.innerText?.trim() ? `${(0, import_core.truncate)(element.innerText.trim(), 30)} \xB7 ` : "";
|
|
40
|
+
return `${textPreview}${fileName}${lineInfo}`;
|
|
41
|
+
}
|
|
42
|
+
function useSelection(options) {
|
|
43
|
+
const bubbleVisible = (0, import_vue.computed)(() => options.selectMode.value);
|
|
44
|
+
const selectedElementItems = (0, import_vue.computed)(
|
|
45
|
+
() => (options.selectedElements.value || []).map(
|
|
46
|
+
(element, index) => ({
|
|
47
|
+
key: getElementKey(element, index),
|
|
48
|
+
description: element.description || "\u672A\u77E5\u5143\u7D20",
|
|
49
|
+
bubbleFileText: getBubbleFileText(element),
|
|
50
|
+
panelFileText: getPanelFileText(element),
|
|
51
|
+
element
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
const hasSelectedElements = (0, import_vue.computed)(() => selectedElementItems.value.length > 0);
|
|
56
|
+
function handleToggleSelectMode() {
|
|
57
|
+
options.onToggleSelectMode(!options.selectMode.value);
|
|
58
|
+
}
|
|
59
|
+
function handleClickSelectedNode(item) {
|
|
60
|
+
const description = item.element.description;
|
|
61
|
+
if (!description) return;
|
|
62
|
+
let targetElement = null;
|
|
63
|
+
if (description.includes("#")) {
|
|
64
|
+
const idMatch = description.match(/#([^.[\s]+)/);
|
|
65
|
+
if (idMatch) {
|
|
66
|
+
targetElement = document.getElementById(idMatch[1]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!targetElement && description.includes(".")) {
|
|
70
|
+
const classMatch = description.match(/^([a-z]+)\.([^[\s]+)/i);
|
|
71
|
+
if (classMatch) {
|
|
72
|
+
const tagName = classMatch[1];
|
|
73
|
+
const classes = classMatch[2].split(".").filter(Boolean);
|
|
74
|
+
const selector = `${tagName}.${classes.join(".")}`;
|
|
75
|
+
targetElement = document.querySelector(selector);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!targetElement) {
|
|
79
|
+
const tagMatch = description.match(/^([a-z]+)/i);
|
|
80
|
+
if (tagMatch) {
|
|
81
|
+
const simpleSelector = description.split(/[.[\s]/)[0];
|
|
82
|
+
targetElement = document.querySelector(simpleSelector);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (targetElement) {
|
|
86
|
+
targetElement.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
87
|
+
const highlightOverlay = document.createElement("div");
|
|
88
|
+
highlightOverlay.className = "aipanel-element-highlight-temp";
|
|
89
|
+
const widget = document.querySelector(".aipanel-widget");
|
|
90
|
+
let primary = "#3b82f6";
|
|
91
|
+
let primaryBg = "rgba(59, 130, 246, 0.1)";
|
|
92
|
+
if (widget) {
|
|
93
|
+
const style = getComputedStyle(widget);
|
|
94
|
+
primary = style.getPropertyValue("--ap-primary").trim() || primary;
|
|
95
|
+
primaryBg = style.getPropertyValue("--ap-primary-bg").trim() || primaryBg;
|
|
96
|
+
}
|
|
97
|
+
highlightOverlay.style.border = `2px solid ${primary}`;
|
|
98
|
+
highlightOverlay.style.background = primaryBg;
|
|
99
|
+
const rect = targetElement.getBoundingClientRect();
|
|
100
|
+
highlightOverlay.style.top = `${rect.top + window.scrollY}px`;
|
|
101
|
+
highlightOverlay.style.left = `${rect.left + window.scrollX}px`;
|
|
102
|
+
highlightOverlay.style.width = `${rect.width}px`;
|
|
103
|
+
highlightOverlay.style.height = `${rect.height}px`;
|
|
104
|
+
document.body.appendChild(highlightOverlay);
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
highlightOverlay.remove();
|
|
107
|
+
}, 2e3);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function handleRemoveSelectedNode(item, index, source) {
|
|
111
|
+
options.onRemoveSelectedNode({ element: item.element, index, source });
|
|
112
|
+
}
|
|
113
|
+
async function handleClearSelectedNodes() {
|
|
114
|
+
if (!options.selectedElements.value || options.selectedElements.value.length === 0) return;
|
|
115
|
+
const confirmed = await options.showConfirmDialog(
|
|
116
|
+
`\u786E\u5B9A\u8981\u6E05\u7A7A\u6240\u6709 ${options.selectedElements.value.length} \u4E2A\u5DF2\u9009\u8282\u70B9\u5417\uFF1F`
|
|
117
|
+
);
|
|
118
|
+
if (confirmed) {
|
|
119
|
+
options.onClearSelectedNodes();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
bubbleVisible,
|
|
124
|
+
hasSelectedElements,
|
|
125
|
+
selectedElementItems,
|
|
126
|
+
handleClearSelectedNodes,
|
|
127
|
+
handleClickSelectedNode,
|
|
128
|
+
handleRemoveSelectedNode,
|
|
129
|
+
handleToggleSelectMode
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { AIPanelRemoveSelectedPayload, AIPanelSelectedElement, AIPanelSelectedElementItem } from "../src/types";
|
|
3
|
+
export interface UseSelectionOptions {
|
|
4
|
+
selectMode: Ref<boolean>;
|
|
5
|
+
selectedElements: Ref<AIPanelSelectedElement[]>;
|
|
6
|
+
onToggleSelectMode: (mode: boolean) => void;
|
|
7
|
+
onRemoveSelectedNode: (payload: AIPanelRemoveSelectedPayload) => void;
|
|
8
|
+
onClearSelectedNodes: () => void;
|
|
9
|
+
showConfirmDialog: (message: string) => Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
export declare function useSelection(options: UseSelectionOptions): {
|
|
12
|
+
bubbleVisible: import("vue").ComputedRef<boolean>;
|
|
13
|
+
hasSelectedElements: import("vue").ComputedRef<boolean>;
|
|
14
|
+
selectedElementItems: import("vue").ComputedRef<AIPanelSelectedElementItem[]>;
|
|
15
|
+
handleClearSelectedNodes: () => Promise<void>;
|
|
16
|
+
handleClickSelectedNode: (item: AIPanelSelectedElementItem) => void;
|
|
17
|
+
handleRemoveSelectedNode: (item: AIPanelSelectedElementItem, index: number, source: AIPanelRemoveSelectedPayload["source"]) => void;
|
|
18
|
+
handleToggleSelectMode: () => void;
|
|
19
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var use_session_exports = {};
|
|
19
|
+
__export(use_session_exports, {
|
|
20
|
+
useSession: () => useSession
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(use_session_exports);
|
|
23
|
+
var import_vue = require("vue");
|
|
24
|
+
function formatSessionMeta(session) {
|
|
25
|
+
if (session.meta) {
|
|
26
|
+
return session.meta;
|
|
27
|
+
}
|
|
28
|
+
if (!session.updatedAt) {
|
|
29
|
+
return "";
|
|
30
|
+
}
|
|
31
|
+
const date = new Date(session.updatedAt);
|
|
32
|
+
if (Number.isNaN(date.getTime())) {
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
|
|
36
|
+
}
|
|
37
|
+
function useSession(options) {
|
|
38
|
+
const sessionItems = (0, import_vue.computed)(
|
|
39
|
+
() => (options.sessions.value || []).map((session) => ({
|
|
40
|
+
key: session.id,
|
|
41
|
+
id: session.id,
|
|
42
|
+
title: session.title || "\u65B0\u4F1A\u8BDD",
|
|
43
|
+
meta: formatSessionMeta(session),
|
|
44
|
+
active: session.id === options.currentSessionId.value,
|
|
45
|
+
session
|
|
46
|
+
}))
|
|
47
|
+
);
|
|
48
|
+
function handleCreateSession() {
|
|
49
|
+
options.onCreateSession();
|
|
50
|
+
}
|
|
51
|
+
function handleSelectSession(item) {
|
|
52
|
+
options.onSelectSession(item.session);
|
|
53
|
+
}
|
|
54
|
+
async function handleDeleteSession(item) {
|
|
55
|
+
const confirmed = await options.showConfirmDialog(`\u786E\u5B9A\u8981\u5220\u9664\u4F1A\u8BDD "${item.title}" \u5417\uFF1F`);
|
|
56
|
+
if (confirmed) {
|
|
57
|
+
options.onDeleteSession(item.session);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
sessionItems,
|
|
62
|
+
handleCreateSession,
|
|
63
|
+
handleDeleteSession,
|
|
64
|
+
handleSelectSession
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { AIPanelWidgetSession, AIPanelWidgetSessionItem } from "../src/types";
|
|
3
|
+
export interface UseSessionOptions {
|
|
4
|
+
sessions: Ref<AIPanelWidgetSession[]>;
|
|
5
|
+
currentSessionId: Ref<string | number | null>;
|
|
6
|
+
onCreateSession: () => void;
|
|
7
|
+
onSelectSession: (session: AIPanelWidgetSession) => void;
|
|
8
|
+
onDeleteSession: (session: AIPanelWidgetSession) => void;
|
|
9
|
+
showConfirmDialog: (message: string) => Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
export declare function useSession(options: UseSessionOptions): {
|
|
12
|
+
sessionItems: import("vue").ComputedRef<AIPanelWidgetSessionItem[]>;
|
|
13
|
+
handleCreateSession: () => void;
|
|
14
|
+
handleDeleteSession: (item: AIPanelWidgetSessionItem) => Promise<void>;
|
|
15
|
+
handleSelectSession: (item: AIPanelWidgetSessionItem) => void;
|
|
16
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var use_split_exports = {};
|
|
19
|
+
__export(use_split_exports, {
|
|
20
|
+
useSplitMode: () => useSplitMode
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(use_split_exports);
|
|
23
|
+
var import_vue = require("vue");
|
|
24
|
+
const AUTO_MODE_THRESHOLD = 1440;
|
|
25
|
+
function useSplitMode(options) {
|
|
26
|
+
const windowWidth = (0, import_vue.ref)(typeof window !== "undefined" ? window.innerWidth : 0);
|
|
27
|
+
const localSplitPosition = (0, import_vue.ref)(options.splitPosition?.value ?? "right");
|
|
28
|
+
const isExtensionMode = (0, import_vue.computed)(() => options.displayMode.value === "extension");
|
|
29
|
+
const shouldSkipBodyModification = (0, import_vue.computed)(
|
|
30
|
+
() => isExtensionMode.value || options.displayMode.value === "extension-selector"
|
|
31
|
+
);
|
|
32
|
+
const splitConfig = (0, import_vue.computed)(() => {
|
|
33
|
+
const config = options.splitMode.value || {};
|
|
34
|
+
const isExt = isExtensionMode.value;
|
|
35
|
+
return {
|
|
36
|
+
width: config.width ?? 500,
|
|
37
|
+
minWidth: config.minWidth ?? 400,
|
|
38
|
+
maxWidth: config.maxWidth ?? 800,
|
|
39
|
+
resizable: isExt ? false : config.resizable ?? true,
|
|
40
|
+
shrinkPage: isExt ? false : config.shrinkPage ?? true,
|
|
41
|
+
defaultOpen: isExt ? true : config.defaultOpen ?? true,
|
|
42
|
+
position: config.position ?? localSplitPosition.value
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
const panelWidth = (0, import_vue.ref)(splitConfig.value.width);
|
|
46
|
+
const effectiveMode = (0, import_vue.computed)(() => {
|
|
47
|
+
if (isExtensionMode.value) return "split";
|
|
48
|
+
if (options.displayMode.value === "bubble") {
|
|
49
|
+
return "bubble";
|
|
50
|
+
}
|
|
51
|
+
if (options.displayMode.value === "split") {
|
|
52
|
+
return "split";
|
|
53
|
+
}
|
|
54
|
+
return windowWidth.value >= AUTO_MODE_THRESHOLD ? "split" : "bubble";
|
|
55
|
+
});
|
|
56
|
+
const isSplitMode = (0, import_vue.computed)(() => effectiveMode.value === "split");
|
|
57
|
+
const splitPosition = (0, import_vue.computed)(() => splitConfig.value.position);
|
|
58
|
+
const handleResize = (width) => {
|
|
59
|
+
panelWidth.value = width;
|
|
60
|
+
options.onWidthChange?.(width);
|
|
61
|
+
};
|
|
62
|
+
const handleToggle = () => {
|
|
63
|
+
const nextOpen = !options.open.value;
|
|
64
|
+
options.onOpenChange?.(nextOpen);
|
|
65
|
+
};
|
|
66
|
+
const handleTogglePosition = () => {
|
|
67
|
+
const nextPosition = localSplitPosition.value === "right" ? "left" : "right";
|
|
68
|
+
localSplitPosition.value = nextPosition;
|
|
69
|
+
options.onPositionChange?.(nextPosition);
|
|
70
|
+
};
|
|
71
|
+
const handleWindowResize = () => {
|
|
72
|
+
if (typeof window !== "undefined") {
|
|
73
|
+
windowWidth.value = window.innerWidth;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const updateBodyClass = () => {
|
|
77
|
+
if (typeof document === "undefined") return;
|
|
78
|
+
if (shouldSkipBodyModification.value) {
|
|
79
|
+
document.body.classList.remove("has-aipanel-split");
|
|
80
|
+
document.body.classList.remove("has-aipanel-split-left");
|
|
81
|
+
document.body.classList.remove("has-aipanel-split-right");
|
|
82
|
+
document.body.style.removeProperty("--aipanel-split-width");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const shouldShrink = isSplitMode.value && options.open.value && splitConfig.value.shrinkPage;
|
|
86
|
+
if (shouldShrink) {
|
|
87
|
+
document.body.classList.add("has-aipanel-split");
|
|
88
|
+
document.body.style.setProperty("--aipanel-split-width", `${panelWidth.value}px`);
|
|
89
|
+
if (splitPosition.value === "left") {
|
|
90
|
+
document.body.classList.add("has-aipanel-split-left");
|
|
91
|
+
document.body.classList.remove("has-aipanel-split-right");
|
|
92
|
+
} else {
|
|
93
|
+
document.body.classList.add("has-aipanel-split-right");
|
|
94
|
+
document.body.classList.remove("has-aipanel-split-left");
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
document.body.classList.remove("has-aipanel-split");
|
|
98
|
+
document.body.classList.remove("has-aipanel-split-left");
|
|
99
|
+
document.body.classList.remove("has-aipanel-split-right");
|
|
100
|
+
document.body.style.removeProperty("--aipanel-split-width");
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
(0, import_vue.watch)([isSplitMode, options.open, panelWidth, splitPosition], updateBodyClass, {
|
|
104
|
+
immediate: true
|
|
105
|
+
});
|
|
106
|
+
(0, import_vue.watch)(splitConfig, (config) => {
|
|
107
|
+
if (panelWidth.value < config.minWidth) {
|
|
108
|
+
panelWidth.value = config.minWidth;
|
|
109
|
+
}
|
|
110
|
+
if (panelWidth.value > config.maxWidth) {
|
|
111
|
+
panelWidth.value = config.maxWidth;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
(0, import_vue.watch)(
|
|
115
|
+
() => options.splitPosition?.value,
|
|
116
|
+
(val) => {
|
|
117
|
+
if (val && val !== localSplitPosition.value) {
|
|
118
|
+
localSplitPosition.value = val;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
(0, import_vue.onMounted)(() => {
|
|
123
|
+
if (typeof window !== "undefined") {
|
|
124
|
+
window.addEventListener("resize", handleWindowResize);
|
|
125
|
+
if (!isExtensionMode.value && isSplitMode.value && splitConfig.value.defaultOpen && !options.open.value) {
|
|
126
|
+
options.onOpenChange?.(true);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
(0, import_vue.onUnmounted)(() => {
|
|
131
|
+
if (typeof window !== "undefined") {
|
|
132
|
+
window.removeEventListener("resize", handleWindowResize);
|
|
133
|
+
if (!isExtensionMode.value) {
|
|
134
|
+
document.body.classList.remove("has-aipanel-split");
|
|
135
|
+
document.body.classList.remove("has-aipanel-split-left");
|
|
136
|
+
document.body.classList.remove("has-aipanel-split-right");
|
|
137
|
+
document.body.style.removeProperty("--aipanel-split-width");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
effectiveMode,
|
|
143
|
+
isSplitMode,
|
|
144
|
+
isExtensionMode,
|
|
145
|
+
panelWidth,
|
|
146
|
+
splitConfig,
|
|
147
|
+
splitPosition,
|
|
148
|
+
handleResize,
|
|
149
|
+
handleToggle,
|
|
150
|
+
handleTogglePosition
|
|
151
|
+
};
|
|
152
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { DisplayMode, SplitModeOptions } from "@aipanel/core";
|
|
3
|
+
export interface UseSplitModeOptions {
|
|
4
|
+
displayMode: Ref<DisplayMode>;
|
|
5
|
+
splitMode: Ref<SplitModeOptions | undefined>;
|
|
6
|
+
open: Ref<boolean>;
|
|
7
|
+
splitPosition?: Ref<"left" | "right">;
|
|
8
|
+
onOpenChange?: (open: boolean) => void;
|
|
9
|
+
onWidthChange?: (width: number) => void;
|
|
10
|
+
onPositionChange?: (position: "left" | "right") => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function useSplitMode(options: UseSplitModeOptions): {
|
|
13
|
+
effectiveMode: import("vue").ComputedRef<"bubble" | "split">;
|
|
14
|
+
isSplitMode: import("vue").ComputedRef<boolean>;
|
|
15
|
+
isExtensionMode: import("vue").ComputedRef<boolean>;
|
|
16
|
+
panelWidth: Ref<number, number>;
|
|
17
|
+
splitConfig: import("vue").ComputedRef<{
|
|
18
|
+
width: number;
|
|
19
|
+
minWidth: number;
|
|
20
|
+
maxWidth: number;
|
|
21
|
+
resizable: boolean;
|
|
22
|
+
shrinkPage: boolean;
|
|
23
|
+
defaultOpen: boolean;
|
|
24
|
+
position: "left" | "right";
|
|
25
|
+
}>;
|
|
26
|
+
splitPosition: import("vue").ComputedRef<"left" | "right">;
|
|
27
|
+
handleResize: (width: number) => void;
|
|
28
|
+
handleToggle: () => void;
|
|
29
|
+
handleTogglePosition: () => void;
|
|
30
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var use_widget_exports = {};
|
|
19
|
+
__export(use_widget_exports, {
|
|
20
|
+
useWidget: () => useWidget
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(use_widget_exports);
|
|
23
|
+
var import_vue = require("vue");
|
|
24
|
+
const THEME_CYCLE = ["auto", "light", "dark"];
|
|
25
|
+
function useWidget(options) {
|
|
26
|
+
const systemTheme = (0, import_vue.ref)("light");
|
|
27
|
+
function getSystemTheme() {
|
|
28
|
+
if (typeof window === "undefined") return "light";
|
|
29
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
30
|
+
}
|
|
31
|
+
let mediaQuery = null;
|
|
32
|
+
let handleChange = null;
|
|
33
|
+
(0, import_vue.onMounted)(() => {
|
|
34
|
+
if (typeof window === "undefined") return;
|
|
35
|
+
systemTheme.value = getSystemTheme();
|
|
36
|
+
mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
37
|
+
handleChange = (e) => {
|
|
38
|
+
systemTheme.value = e.matches ? "dark" : "light";
|
|
39
|
+
};
|
|
40
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
41
|
+
});
|
|
42
|
+
(0, import_vue.onUnmounted)(() => {
|
|
43
|
+
if (mediaQuery && handleChange) {
|
|
44
|
+
mediaQuery.removeEventListener("change", handleChange);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const resolvedTheme = (0, import_vue.computed)(() => {
|
|
48
|
+
if (options.theme.value === "auto") {
|
|
49
|
+
return systemTheme.value;
|
|
50
|
+
}
|
|
51
|
+
return options.theme.value;
|
|
52
|
+
});
|
|
53
|
+
const containerClasses = (0, import_vue.computed)(() => [
|
|
54
|
+
"aipanel-widget",
|
|
55
|
+
`aipanel-theme-${resolvedTheme.value}`
|
|
56
|
+
]);
|
|
57
|
+
const buttonActive = (0, import_vue.computed)(() => !!(options.open.value || options.selectMode.value));
|
|
58
|
+
const iframeSource = (0, import_vue.computed)(() => options.iframeSrc.value || "about:blank");
|
|
59
|
+
const sessionListTitle = (0, import_vue.computed)(
|
|
60
|
+
() => options.sessionListCollapsed.value ? "\u5C55\u5F00\u4F1A\u8BDD\u5217\u8868" : "\u6298\u53E0\u4F1A\u8BDD\u5217\u8868"
|
|
61
|
+
);
|
|
62
|
+
function handleToggle() {
|
|
63
|
+
if (options.selectMode.value) {
|
|
64
|
+
options.onToggleSelectMode?.(false);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const nextOpen = !options.open.value;
|
|
68
|
+
options.onToggle(nextOpen);
|
|
69
|
+
}
|
|
70
|
+
function handleClose() {
|
|
71
|
+
options.onClose();
|
|
72
|
+
}
|
|
73
|
+
function handleToggleSessionList() {
|
|
74
|
+
options.onToggleSessionList(!options.sessionListCollapsed.value);
|
|
75
|
+
}
|
|
76
|
+
function handleEmptyAction() {
|
|
77
|
+
options.onEmptyAction();
|
|
78
|
+
}
|
|
79
|
+
function handleToggleTheme() {
|
|
80
|
+
const currentIndex = THEME_CYCLE.indexOf(options.theme.value);
|
|
81
|
+
const nextIndex = (currentIndex + 1) % THEME_CYCLE.length;
|
|
82
|
+
const nextTheme = THEME_CYCLE[nextIndex];
|
|
83
|
+
options.onToggleTheme?.(nextTheme);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
buttonActive,
|
|
87
|
+
containerClasses,
|
|
88
|
+
iframeSource,
|
|
89
|
+
sessionListTitle,
|
|
90
|
+
resolvedTheme,
|
|
91
|
+
handleClose,
|
|
92
|
+
handleEmptyAction,
|
|
93
|
+
handleToggle,
|
|
94
|
+
handleToggleSessionList,
|
|
95
|
+
handleToggleTheme
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { AIPanelWidgetTheme } from "../src/types";
|
|
3
|
+
export interface UseWidgetOptions {
|
|
4
|
+
theme: Ref<string>;
|
|
5
|
+
open: Ref<boolean>;
|
|
6
|
+
selectMode: Ref<boolean>;
|
|
7
|
+
iframeSrc: Ref<string>;
|
|
8
|
+
sessionListCollapsed: Ref<boolean>;
|
|
9
|
+
onToggle: (nextOpen: boolean) => void;
|
|
10
|
+
onToggleSelectMode?: (mode: boolean) => void;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
onToggleSessionList: (collapsed: boolean) => void;
|
|
13
|
+
onEmptyAction: () => void;
|
|
14
|
+
onToggleTheme?: (theme: AIPanelWidgetTheme) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function useWidget(options: UseWidgetOptions): {
|
|
17
|
+
buttonActive: import("vue").ComputedRef<boolean>;
|
|
18
|
+
containerClasses: import("vue").ComputedRef<string[]>;
|
|
19
|
+
iframeSource: import("vue").ComputedRef<string>;
|
|
20
|
+
sessionListTitle: import("vue").ComputedRef<"展开会话列表" | "折叠会话列表">;
|
|
21
|
+
resolvedTheme: import("vue").ComputedRef<"light" | "dark">;
|
|
22
|
+
handleClose: () => void;
|
|
23
|
+
handleEmptyAction: () => void;
|
|
24
|
+
handleToggle: () => void;
|
|
25
|
+
handleToggleSessionList: () => void;
|
|
26
|
+
handleToggleTheme: () => void;
|
|
27
|
+
};
|