@vite-plugin-opencode-assistant/components 1.0.26 → 1.0.27
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/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/open-code-widget/composables/use-inspector.js +118 -79
- package/es/open-code-widget/composables/use-persist-state.d.ts +24 -0
- package/es/open-code-widget/composables/use-persist-state.js +59 -0
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -1
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +2 -2
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.js +37 -21
- package/es/open-code-widget/src/components/Trigger.vue.d.ts +0 -2
- package/es/open-code-widget/src/components/Trigger.vue.js +10 -27
- package/es/open-code-widget/src/context.d.ts +3 -0
- package/es/open-code-widget/src/index-sfc.css +1 -1
- package/es/open-code-widget/src/index.vue.d.ts +10 -10
- package/es/open-code-widget/src/index.vue.js +107 -29
- package/lib/@vite-plugin-opencode-assistant/components.cjs.js +304 -140
- package/lib/@vite-plugin-opencode-assistant/components.es.js +305 -141
- package/lib/components.css +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/open-code-widget/composables/use-inspector.js +118 -79
- package/lib/open-code-widget/composables/use-persist-state.d.ts +24 -0
- package/lib/open-code-widget/composables/use-persist-state.js +78 -0
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -1
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +2 -2
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.js +37 -21
- package/lib/open-code-widget/src/components/Trigger.vue.d.ts +0 -2
- package/lib/open-code-widget/src/components/Trigger.vue.js +10 -27
- package/lib/open-code-widget/src/context.d.ts +3 -0
- package/lib/open-code-widget/src/index-sfc.css +1 -1
- package/lib/open-code-widget/src/index.vue.d.ts +10 -10
- package/lib/open-code-widget/src/index.vue.js +106 -28
- package/lib/web-types.json +1 -1
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Ref } from "vue";
|
|
2
2
|
import type { OpenCodeWidgetSessionItem, OpenCodeSelectedElementItem, OpenCodeRemoveSelectedPayload } from "./types";
|
|
3
|
+
import type { FloatingBubbleOffset } from "./components/FloatingBubble/types";
|
|
3
4
|
export interface OpenCodeWidgetContext {
|
|
4
5
|
theme: Ref<string>;
|
|
5
6
|
resolvedTheme: Ref<"light" | "dark">;
|
|
@@ -22,6 +23,7 @@ export interface OpenCodeWidgetContext {
|
|
|
22
23
|
thinking: Ref<boolean>;
|
|
23
24
|
minimized: Ref<boolean>;
|
|
24
25
|
promptDockVisible: Ref<boolean>;
|
|
26
|
+
bubbleOffset: Ref<FloatingBubbleOffset | undefined>;
|
|
25
27
|
iframeSource: Ref<string>;
|
|
26
28
|
buttonActive: Ref<boolean>;
|
|
27
29
|
sessionListTitle: Ref<string>;
|
|
@@ -48,6 +50,7 @@ export interface OpenCodeWidgetContext {
|
|
|
48
50
|
}) => void;
|
|
49
51
|
handleClearSelectedNodes: () => void;
|
|
50
52
|
handleFrameLoaded: () => void;
|
|
53
|
+
handleBubbleOffsetChange: (offset: FloatingBubbleOffset | undefined) => void;
|
|
51
54
|
}
|
|
52
55
|
export declare function provideOpenCodeWidgetContext(context: OpenCodeWidgetContext): void;
|
|
53
56
|
export declare function useOpenCodeWidgetContext(): OpenCodeWidgetContext;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.opencode-widget{--oc-bg-main: #ffffff;--oc-bg-secondary: #f8f9fa;--oc-bg-tertiary: #f3f4f6;--oc-overlay-bg: rgba(255, 255, 255, .9);--oc-bg-inverse: #1e1e1e;--oc-text-primary: #282828;--oc-text-secondary: #4b5563;--oc-text-tertiary: #6b7280;--oc-text-placeholder: #9ca3af;--oc-text-inverse: #ffffff;--oc-border-primary: #e5e7eb;--oc-border-secondary: #d1d5db;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .1);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(0, 0, 0, .5);--oc-tooltip-bg: #1e1e1e;--oc-dialog-overlay: rgba(0, 0, 0, .5);--oc-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--oc-skeleton-bg: #e5e7eb;--oc-skeleton-gradient: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .1);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .15);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .12);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .3);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .2);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .3);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .3);--oc-trigger-bg: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);position:fixed;z-index:999999;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-widget.opencode-theme-dark{--oc-bg-main: #1a1a1a;--oc-bg-secondary: #1e1e1e;--oc-bg-tertiary: #282828;--oc-overlay-bg: rgba(26, 26, 26, .9);--oc-bg-inverse: #ffffff;--oc-text-primary: #f3f4f6;--oc-text-secondary: #d1d5db;--oc-text-tertiary: #9ca3af;--oc-text-placeholder: #6b7280;--oc-text-inverse: #282828;--oc-border-primary: #282828;--oc-border-secondary: #4b5563;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .15);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(26, 26, 26, .9);--oc-tooltip-bg: #282828;--oc-dialog-overlay: rgba(0, 0, 0, .7);--oc-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--oc-skeleton-bg: #151515;--oc-skeleton-gradient: linear-gradient(90deg, #282828 25%, #4b5563 50%, #282828 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .3);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .6);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .3);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .4);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .4);--oc-trigger-bg: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-
|
|
1
|
+
.opencode-widget{--oc-bg-main: #ffffff;--oc-bg-secondary: #f8f9fa;--oc-bg-tertiary: #f3f4f6;--oc-overlay-bg: rgba(255, 255, 255, .9);--oc-bg-inverse: #1e1e1e;--oc-text-primary: #282828;--oc-text-secondary: #4b5563;--oc-text-tertiary: #6b7280;--oc-text-placeholder: #9ca3af;--oc-text-inverse: #ffffff;--oc-border-primary: #e5e7eb;--oc-border-secondary: #d1d5db;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .1);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(0, 0, 0, .5);--oc-tooltip-bg: #1e1e1e;--oc-dialog-overlay: rgba(0, 0, 0, .5);--oc-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--oc-skeleton-bg: #e5e7eb;--oc-skeleton-gradient: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .1);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .15);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .12);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .3);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .2);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .3);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .3);--oc-trigger-bg: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);position:fixed;z-index:999999;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-widget.opencode-theme-dark{--oc-bg-main: #1a1a1a;--oc-bg-secondary: #1e1e1e;--oc-bg-tertiary: #282828;--oc-overlay-bg: rgba(26, 26, 26, .9);--oc-bg-inverse: #ffffff;--oc-text-primary: #f3f4f6;--oc-text-secondary: #d1d5db;--oc-text-tertiary: #9ca3af;--oc-text-placeholder: #6b7280;--oc-text-inverse: #282828;--oc-border-primary: #282828;--oc-border-secondary: #4b5563;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .15);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(26, 26, 26, .9);--oc-tooltip-bg: #282828;--oc-dialog-overlay: rgba(0, 0, 0, .7);--oc-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--oc-skeleton-bg: #151515;--oc-skeleton-gradient: linear-gradient(90deg, #282828 25%, #4b5563 50%, #282828 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .3);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .6);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .3);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .4);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .4);--oc-trigger-bg: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.open{opacity:1;visibility:visible;transform:translateZ(0) scale(1)}.opencode-chat.no-transition,.opencode-chat.no-transition.open{transition:none!important}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-notification{position:absolute;top:20px;left:50%;transform:translate(-50%);padding:12px 24px;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;border-radius:10px;font-size:14px;font-weight:500;box-shadow:0 4px 16px rgba(59,130,246,.4),0 0 0 2px rgba(59,130,246,.2);animation:slideDown .3s ease;z-index:10000000;display:flex;align-items:center;gap:10px}.opencode-notification:before{content:"\1f4a1";font-size:16px}.opencode-dialog-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--oc-dialog-overlay);display:flex;align-items:center;justify-content:center;z-index:9999999;animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.opencode-dialog{background:var(--oc-bg-main);border-radius:12px;padding:24px;min-width:320px;max-width:400px;box-shadow:var(--oc-shadow-xl);animation:scaleIn .2s ease}@keyframes scaleIn{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}.opencode-dialog-content{margin-bottom:20px}.opencode-dialog-message{font-size:15px;color:var(--oc-text-primary);line-height:1.5}.opencode-dialog-actions{display:flex;gap:12px;justify-content:flex-end}.opencode-dialog-btn{padding:10px 20px;border-radius:8px;border:none;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.opencode-dialog-btn.cancel{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-dialog-btn.cancel:hover{background:var(--oc-text-primary);color:var(--oc-bg-main)}.opencode-dialog-btn.confirm{background:var(--oc-danger);color:#fff}.opencode-dialog-btn.confirm:hover{background:var(--oc-danger-hover)}@keyframes slideDown{0%{transform:translate(-50%) translateY(-100%);opacity:0}to{transform:translate(-50%) translateY(0);opacity:1}}.opencode-page-notification{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:12px 24px;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;border-radius:10px;font-size:14px;font-weight:500;box-shadow:0 4px 16px rgba(59,130,246,.4),0 0 0 2px rgba(59,130,246,.2);animation:slideDown .3s ease;z-index:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.opencode-element-highlight{position:fixed;pointer-events:none;z-index:999998;border-radius:4px}#vue-inspector-container{display:none!important}.opencode-element-tooltip{position:fixed;background:var(--oc-tooltip-bg);color:#fff;padding:8px 12px;border-radius:6px;font-size:12px;z-index:9999998;box-shadow:var(--oc-shadow-md);max-width:300px;pointer-events:none}.opencode-tooltip-tag{font-weight:500;margin-bottom:4px;word-break:break-all}.opencode-tooltip-file{font-size:11px;color:var(--oc-text-placeholder);word-break:break-all}.opencode-element-highlight-temp{position:absolute;pointer-events:none;z-index:999998;border-radius:4px;animation:highlight-pulse 2s ease-out forwards}@keyframes highlight-pulse{0%{opacity:1;transform:scale(1)}50%{opacity:.8;transform:scale(1.02)}to{opacity:0;transform:scale(1)}}@media(max-width:768px){.opencode-chat{width:calc(100vw - 40px);height:calc(100vh - 100px)}}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import type { OpenCodeWidgetProps } from "./types";
|
|
2
|
-
declare var
|
|
2
|
+
declare var __VLS_11: {}, __VLS_16: {}, __VLS_18: {}, __VLS_20: {}, __VLS_25: {}, __VLS_32: {}, __VLS_34: {}, __VLS_36: {}, __VLS_38: {};
|
|
3
3
|
type __VLS_Slots = {} & {
|
|
4
|
-
'button-icon'?: (props: typeof
|
|
4
|
+
'button-icon'?: (props: typeof __VLS_11) => any;
|
|
5
5
|
} & {
|
|
6
|
-
'session-toggle-icon'?: (props: typeof
|
|
6
|
+
'session-toggle-icon'?: (props: typeof __VLS_16) => any;
|
|
7
7
|
} & {
|
|
8
|
-
'select-icon'?: (props: typeof
|
|
8
|
+
'select-icon'?: (props: typeof __VLS_18) => any;
|
|
9
9
|
} & {
|
|
10
|
-
'close-icon'?: (props: typeof
|
|
10
|
+
'close-icon'?: (props: typeof __VLS_20) => any;
|
|
11
11
|
} & {
|
|
12
|
-
'sessions-empty'?: (props: typeof
|
|
12
|
+
'sessions-empty'?: (props: typeof __VLS_25) => any;
|
|
13
13
|
} & {
|
|
14
|
-
'empty-state'?: (props: typeof
|
|
14
|
+
'empty-state'?: (props: typeof __VLS_32) => any;
|
|
15
15
|
} & {
|
|
16
|
-
loading?: (props: typeof
|
|
16
|
+
loading?: (props: typeof __VLS_34) => any;
|
|
17
17
|
} & {
|
|
18
|
-
error?: (props: typeof
|
|
18
|
+
error?: (props: typeof __VLS_36) => any;
|
|
19
19
|
} & {
|
|
20
|
-
content?: (props: typeof
|
|
20
|
+
content?: (props: typeof __VLS_38) => any;
|
|
21
21
|
};
|
|
22
22
|
declare const __VLS_component: import("vue").DefineComponent<OpenCodeWidgetProps, {
|
|
23
23
|
showNotification: (message: string, options?: {
|
|
@@ -60,6 +60,7 @@ var import_use_selection = require("../composables/use-selection");
|
|
|
60
60
|
var import_use_session = require("../composables/use-session");
|
|
61
61
|
var import_use_widget = require("../composables/use-widget");
|
|
62
62
|
var import_use_inspector = require("../composables/use-inspector");
|
|
63
|
+
var import_use_persist_state = require("../composables/use-persist-state");
|
|
63
64
|
var import_context = require("./context");
|
|
64
65
|
var import_vue3 = require("vue");
|
|
65
66
|
const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProps(__spreadValues({}, {
|
|
@@ -137,17 +138,26 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
137
138
|
var _a;
|
|
138
139
|
(_a = frameRef.value) == null ? void 0 : _a.sendMessageToIframe(type, data);
|
|
139
140
|
};
|
|
141
|
+
const localSessionListCollapsed = (0, import_vue2.ref)(props.sessionListCollapsed);
|
|
142
|
+
const minimized = (0, import_vue2.ref)(false);
|
|
143
|
+
const promptDockVisible = (0, import_vue2.ref)(true);
|
|
144
|
+
const isRestoring = (0, import_vue2.ref)(true);
|
|
145
|
+
const iframeLoaded = (0, import_vue2.ref)(false);
|
|
146
|
+
const syncStateToIframe = () => {
|
|
147
|
+
if (!iframeLoaded.value) return;
|
|
148
|
+
sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
|
|
149
|
+
sendMessageToIframe("minimize-state-change", { minimized: minimized.value });
|
|
150
|
+
};
|
|
140
151
|
const handleFrameLoaded = () => {
|
|
141
152
|
emit("frame-loaded");
|
|
153
|
+
iframeLoaded.value = true;
|
|
154
|
+
syncStateToIframe();
|
|
142
155
|
};
|
|
143
156
|
__expose({
|
|
144
157
|
showNotification,
|
|
145
158
|
showConfirmDialog,
|
|
146
159
|
sendMessageToIframe
|
|
147
160
|
});
|
|
148
|
-
const localSessionListCollapsed = (0, import_vue2.ref)(props.sessionListCollapsed);
|
|
149
|
-
const minimized = (0, import_vue2.ref)(false);
|
|
150
|
-
const promptDockVisible = (0, import_vue2.ref)(true);
|
|
151
161
|
(0, import_vue2.watch)(
|
|
152
162
|
() => props.sessionListCollapsed,
|
|
153
163
|
(val) => {
|
|
@@ -244,6 +254,53 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
244
254
|
emit("toggle-select-mode", false);
|
|
245
255
|
}
|
|
246
256
|
});
|
|
257
|
+
const bubbleOffset = (0, import_vue2.ref)(void 0);
|
|
258
|
+
(0, import_use_persist_state.usePersistState)({
|
|
259
|
+
open: (0, import_vue2.toRef)(props, "open"),
|
|
260
|
+
minimized,
|
|
261
|
+
promptDockVisible,
|
|
262
|
+
bubbleOffset,
|
|
263
|
+
theme: (0, import_vue2.toRef)(props, "theme"),
|
|
264
|
+
sessionListCollapsed: localSessionListCollapsed,
|
|
265
|
+
onRestore: (state) => {
|
|
266
|
+
if (state.open !== void 0 && state.open !== props.open) {
|
|
267
|
+
emit("update:open", state.open);
|
|
268
|
+
emit("toggle", state.open);
|
|
269
|
+
}
|
|
270
|
+
if (state.minimized !== void 0) {
|
|
271
|
+
minimized.value = state.minimized;
|
|
272
|
+
}
|
|
273
|
+
if (state.bubbleOffset !== void 0) {
|
|
274
|
+
const bubbleSize = 44;
|
|
275
|
+
const margin = 10;
|
|
276
|
+
const maxX = window.innerWidth - bubbleSize - margin;
|
|
277
|
+
const maxY = window.innerHeight - bubbleSize - margin;
|
|
278
|
+
bubbleOffset.value = {
|
|
279
|
+
x: Math.max(margin, Math.min(state.bubbleOffset.x, maxX)),
|
|
280
|
+
y: Math.max(margin, Math.min(state.bubbleOffset.y, maxY))
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
if (state.theme !== void 0 && state.theme !== props.theme) {
|
|
284
|
+
emit("update:theme", state.theme);
|
|
285
|
+
emit("toggle-theme", state.theme);
|
|
286
|
+
}
|
|
287
|
+
if (state.sessionListCollapsed !== void 0 && state.sessionListCollapsed !== props.sessionListCollapsed) {
|
|
288
|
+
localSessionListCollapsed.value = state.sessionListCollapsed;
|
|
289
|
+
emit("update:sessionListCollapsed", state.sessionListCollapsed);
|
|
290
|
+
}
|
|
291
|
+
if (state.promptDockVisible !== void 0) {
|
|
292
|
+
promptDockVisible.value = state.promptDockVisible;
|
|
293
|
+
} else if (minimized.value) {
|
|
294
|
+
promptDockVisible.value = false;
|
|
295
|
+
}
|
|
296
|
+
(0, import_vue2.nextTick)(() => {
|
|
297
|
+
syncStateToIframe();
|
|
298
|
+
setTimeout(() => {
|
|
299
|
+
isRestoring.value = false;
|
|
300
|
+
}, 50);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
});
|
|
247
304
|
const handleToggleMinimize = () => {
|
|
248
305
|
minimized.value = !minimized.value;
|
|
249
306
|
promptDockVisible.value = !minimized.value;
|
|
@@ -254,15 +311,33 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
254
311
|
promptDockVisible.value = !promptDockVisible.value;
|
|
255
312
|
sendMessageToIframe("prompt-dock-visibility-change", { visible: promptDockVisible.value });
|
|
256
313
|
};
|
|
257
|
-
const
|
|
314
|
+
const windowWidth = (0, import_vue2.ref)(typeof window !== "undefined" ? window.innerWidth : 0);
|
|
315
|
+
const windowHeight = (0, import_vue2.ref)(typeof window !== "undefined" ? window.innerHeight : 0);
|
|
316
|
+
const handleWindowResize = () => {
|
|
317
|
+
if (typeof window !== "undefined") {
|
|
318
|
+
windowWidth.value = window.innerWidth;
|
|
319
|
+
windowHeight.value = window.innerHeight;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
(0, import_vue2.onMounted)(() => {
|
|
323
|
+
if (typeof window !== "undefined") {
|
|
324
|
+
window.addEventListener("resize", handleWindowResize);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
(0, import_vue2.onUnmounted)(() => {
|
|
328
|
+
if (typeof window !== "undefined") {
|
|
329
|
+
window.removeEventListener("resize", handleWindowResize);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
258
332
|
const bubbleQuadrant = (0, import_vue2.computed)(() => {
|
|
259
333
|
var _a, _b, _c, _d;
|
|
260
334
|
if (typeof window === "undefined") return "bottom-right";
|
|
261
|
-
const centerX =
|
|
262
|
-
const centerY =
|
|
335
|
+
const centerX = windowWidth.value / 2;
|
|
336
|
+
const centerY = windowHeight.value / 2;
|
|
263
337
|
const bubbleSize = 44;
|
|
264
|
-
const
|
|
265
|
-
const
|
|
338
|
+
const currentOffset = (_b = (_a = triggerRef.value) == null ? void 0 : _a.offset) != null ? _b : bubbleOffset.value;
|
|
339
|
+
const effectiveX = ((_c = currentOffset == null ? void 0 : currentOffset.x) != null ? _c : windowWidth.value - bubbleSize - 24) + bubbleSize / 2;
|
|
340
|
+
const effectiveY = ((_d = currentOffset == null ? void 0 : currentOffset.y) != null ? _d : windowHeight.value - bubbleSize - 24) + bubbleSize / 2;
|
|
266
341
|
if (effectiveX >= centerX && effectiveY >= centerY) {
|
|
267
342
|
return "bottom-right";
|
|
268
343
|
} else if (effectiveX < centerX && effectiveY >= centerY) {
|
|
@@ -278,36 +353,42 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
278
353
|
return quadrant === "top-right" || quadrant === "bottom-right";
|
|
279
354
|
});
|
|
280
355
|
const chatPositionStyle = (0, import_vue2.computed)(() => {
|
|
281
|
-
var _a;
|
|
356
|
+
var _a, _b, _c;
|
|
282
357
|
if (typeof window === "undefined") return {};
|
|
283
|
-
const windowWidth = window.innerWidth;
|
|
284
|
-
const windowHeight = window.innerHeight;
|
|
285
358
|
const chatWidth = minimized.value ? 300 : 700;
|
|
286
|
-
const chatHeight = minimized.value ? 300 : Math.min(windowHeight * 0.86, windowHeight - 40);
|
|
359
|
+
const chatHeight = minimized.value ? 300 : Math.min(windowHeight.value * 0.86, windowHeight.value - 40);
|
|
287
360
|
const gap = 24;
|
|
288
361
|
const bubbleSize = 44;
|
|
289
362
|
const screenMargin = 20;
|
|
290
|
-
const effectiveOffset = (_a = bubbleOffset.value) != null ?
|
|
363
|
+
const effectiveOffset = (_c = (_b = (_a = triggerRef.value) == null ? void 0 : _a.offset) != null ? _b : bubbleOffset.value) != null ? _c : { x: windowWidth.value - bubbleSize - gap, y: windowHeight.value - bubbleSize - gap };
|
|
291
364
|
const style = {};
|
|
292
365
|
if (isBubbleOnRightSide.value) {
|
|
293
|
-
let rightPos = windowWidth - effectiveOffset.x + gap;
|
|
294
|
-
const
|
|
366
|
+
let rightPos = windowWidth.value - effectiveOffset.x + gap;
|
|
367
|
+
const minRight = screenMargin;
|
|
368
|
+
const maxRight = windowWidth.value - chatWidth - screenMargin;
|
|
295
369
|
if (rightPos > maxRight) {
|
|
296
370
|
rightPos = maxRight;
|
|
297
371
|
}
|
|
372
|
+
if (rightPos < minRight) {
|
|
373
|
+
rightPos = minRight;
|
|
374
|
+
}
|
|
298
375
|
style.right = `${rightPos}px`;
|
|
299
376
|
style.left = "auto";
|
|
300
377
|
} else {
|
|
301
378
|
let leftPos = effectiveOffset.x + bubbleSize + gap;
|
|
302
|
-
const
|
|
379
|
+
const minLeft = screenMargin;
|
|
380
|
+
const maxLeft = windowWidth.value - chatWidth - screenMargin;
|
|
303
381
|
if (leftPos > maxLeft) {
|
|
304
382
|
leftPos = maxLeft;
|
|
305
383
|
}
|
|
384
|
+
if (leftPos < minLeft) {
|
|
385
|
+
leftPos = minLeft;
|
|
386
|
+
}
|
|
306
387
|
style.left = `${leftPos}px`;
|
|
307
388
|
style.right = "auto";
|
|
308
389
|
}
|
|
309
|
-
let bottomPos = windowHeight - effectiveOffset.y - bubbleSize;
|
|
310
|
-
const maxBottom = windowHeight - chatHeight - screenMargin;
|
|
390
|
+
let bottomPos = windowHeight.value - effectiveOffset.y - bubbleSize;
|
|
391
|
+
const maxBottom = windowHeight.value - chatHeight - screenMargin;
|
|
311
392
|
if (bottomPos > maxBottom) {
|
|
312
393
|
bottomPos = maxBottom;
|
|
313
394
|
}
|
|
@@ -371,6 +452,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
371
452
|
thinking: (0, import_vue2.toRef)(props, "thinking"),
|
|
372
453
|
minimized,
|
|
373
454
|
promptDockVisible,
|
|
455
|
+
bubbleOffset,
|
|
374
456
|
iframeSource,
|
|
375
457
|
buttonActive,
|
|
376
458
|
sessionListTitle,
|
|
@@ -392,7 +474,8 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
392
474
|
handleClickSelectedNode,
|
|
393
475
|
handleRemoveSelectedNode: (payload) => handleRemoveSelectedNode(payload.item, payload.index, payload.source),
|
|
394
476
|
handleClearSelectedNodes,
|
|
395
|
-
handleFrameLoaded
|
|
477
|
+
handleFrameLoaded,
|
|
478
|
+
handleBubbleOffsetChange
|
|
396
479
|
});
|
|
397
480
|
const __returned__ = { props, emit, slots, notificationMessage, notificationVisible, notificationMode, get notificationTimer() {
|
|
398
481
|
return notificationTimer;
|
|
@@ -402,7 +485,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
402
485
|
return dialogResolve;
|
|
403
486
|
}, set dialogResolve(v) {
|
|
404
487
|
dialogResolve = v;
|
|
405
|
-
}, showConfirmDialog, handleDialogConfirm, handleDialogCancel, frameRef, triggerRef, sendMessageToIframe,
|
|
488
|
+
}, showConfirmDialog, handleDialogConfirm, handleDialogCancel, frameRef, triggerRef, sendMessageToIframe, localSessionListCollapsed, minimized, promptDockVisible, isRestoring, iframeLoaded, syncStateToIframe, handleFrameLoaded, buttonActive, containerClasses, iframeSource, sessionListTitle, resolvedTheme, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList, handleToggleTheme, sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession, bubbleVisible, hasSelectedElements, selectedElementItems, handleClearSelectedNodes, handleClickSelectedNode, handleRemoveSelectedNode, handleToggleSelectMode, highlightVisible, highlightStyle, tooltipVisible, tooltipStyle, tooltipContent, bubbleOffset, handleToggleMinimize, handleTogglePromptDock, windowWidth, windowHeight, handleWindowResize, bubbleQuadrant, isBubbleOnRightSide, chatPositionStyle, handleBubbleOffsetChange, chatAnimationOrigin, isDragging, get wasOpenBeforeDrag() {
|
|
406
489
|
return wasOpenBeforeDrag;
|
|
407
490
|
}, set wasOpenBeforeDrag(v) {
|
|
408
491
|
wasOpenBeforeDrag = v;
|
|
@@ -446,7 +529,6 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
446
529
|
$setup["Trigger"],
|
|
447
530
|
{
|
|
448
531
|
ref: "triggerRef",
|
|
449
|
-
onOffsetChange: $setup.handleBubbleOffsetChange,
|
|
450
532
|
onDragStart: $setup.handleDragStart,
|
|
451
533
|
onDragEnd: $setup.handleDragEnd
|
|
452
534
|
},
|
|
@@ -468,7 +550,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
468
550
|
(0, import_vue3.withDirectives)((0, import_vue3.createElementVNode)(
|
|
469
551
|
"div",
|
|
470
552
|
{
|
|
471
|
-
class: (0, import_vue3.normalizeClass)(["opencode-chat", { open: $props.open, minimized: $setup.minimized, dragging: $setup.isDragging }]),
|
|
553
|
+
class: (0, import_vue3.normalizeClass)(["opencode-chat", { open: $props.open, minimized: $setup.minimized, dragging: $setup.isDragging, "no-transition": $setup.isRestoring }]),
|
|
472
554
|
style: (0, import_vue3.normalizeStyle)($setup.chatPositionStyle)
|
|
473
555
|
},
|
|
474
556
|
[
|
|
@@ -579,9 +661,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
579
661
|
"div",
|
|
580
662
|
{
|
|
581
663
|
class: "opencode-element-highlight",
|
|
582
|
-
style: (0, import_vue3.normalizeStyle)(
|
|
583
|
-
display: $setup.highlightVisible ? "block" : "none"
|
|
584
|
-
}, $setup.highlightStyle))
|
|
664
|
+
style: (0, import_vue3.normalizeStyle)($setup.highlightStyle)
|
|
585
665
|
},
|
|
586
666
|
null,
|
|
587
667
|
4
|
|
@@ -593,9 +673,7 @@ function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
593
673
|
"div",
|
|
594
674
|
{
|
|
595
675
|
class: "opencode-element-tooltip",
|
|
596
|
-
style: (0, import_vue3.normalizeStyle)(
|
|
597
|
-
display: $setup.tooltipVisible ? "block" : "none"
|
|
598
|
-
}, $setup.tooltipStyle))
|
|
676
|
+
style: (0, import_vue3.normalizeStyle)($setup.tooltipStyle)
|
|
599
677
|
},
|
|
600
678
|
[
|
|
601
679
|
(0, import_vue3.createElementVNode)(
|
package/lib/web-types.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json","framework":"vue","name":"@vite-plugin-opencode-assistant/components","version":"1.0.
|
|
1
|
+
{"$schema":"https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json","framework":"vue","name":"@vite-plugin-opencode-assistant/components","version":"1.0.27","contributions":{"html":{"tags":[{"name":"open-code","attributes":[{"name":"","default":"`'bottom-right'`","description":"挂件显示的位置","value":{"type":"`'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'`","kind":"expression"}},{"name":"","default":"`false`","description":"挂件是否打开","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'auto'`","description":"主题模式","value":{"type":"`'light' | 'dark' | 'auto'`","kind":"expression"}},{"name":"","default":"`'AI 助手'`","description":"助手头部显示的标题","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'Ctrl+K'`","description":"快捷键提示文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'按 ESC 或 Ctrl+P 退出'`","description":"选择模式快捷键提示文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`false`","description":"是否进入选择页面元素模式","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`true`","description":"会话列表是否折叠","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'id'`","description":"会话列表项的唯一键字段","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`false`","description":"iframe 是否显示加载状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`undefined`","description":"会话列表是否加载中","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示会话列表骨架屏","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示空状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示错误状态","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`'当前项目暂无会话'`","description":"空状态显示的文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`'立即创建'`","description":"空状态操作按钮文本","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`''`","description":"Web UI 的 URL 来源","value":{"type":"`string`","kind":"expression"}},{"name":"","default":"`[]`","description":"会话列表数据","value":{"type":"`OpenCodeWidgetSession[]`","kind":"expression"}},{"name":"","default":"`null`","description":"当前选中的会话 ID","value":{"type":"`string | null`","kind":"expression"}},{"name":"","default":"`[]`","description":"已选中的元素列表","value":{"type":"`OpenCodeSelectedElement[]`","kind":"expression"}},{"name":"","default":"`true`","description":"是否显示\"一键清空\"按钮","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`true`","description":"是否启用选择模式","value":{"type":"`boolean`","kind":"expression"}},{"name":"","default":"`false`","description":"是否显示思考状态(加载中)","value":{"type":"`boolean`","kind":"expression"}}],"events":[{"name":"`update:open`","description":"当挂件打开或关闭时触发","arguments":[{"name":"open","type":"en"},{"name":"boolean"}]},{"name":"`update:selectMode`","description":"当选择模式切换时触发","arguments":[{"name":"mode","type":"de"},{"name":"boolean"}]},{"name":"`update:sessionListCollapsed`","description":"当会话列表折叠状态改变时触发","arguments":[{"name":"collapsed","type":"ed"},{"name":"boolean"}]},{"name":"`update:currentSessionId`","description":"当选中的会话 ID 改变时触发","arguments":[{"name":"sessionId","type":"Id"},{"name":"string | null"}]},{"name":"`update:selectedElements`","description":"当已选中的元素列表改变时触发","arguments":[{"name":"elements","type":"ts"},{"name":"OpenCodeSelectedElement[]"}]},{"name":"`update:theme`","description":"当主题模式改变时触发","arguments":[{"name":"theme","type":"me"},{"name":"'light' | 'dark' | 'auto'"}]},{"name":"`update:thinking`","description":"当思考状态改变时触发","arguments":[{"name":"thinking","type":"ng"},{"name":"boolean"}]},{"name":"","description":"点击触发挂件开关","arguments":[{"name":"open","type":"en"},{"name":"boolean"}]},{"name":"","description":"点击关闭按钮时触发","arguments":[]},{"name":"`toggle-session-list`","description":"点击会话列表切换按钮时触发","arguments":[{"name":"collapsed","type":"ed"},{"name":"boolean"}]},{"name":"`toggle-select-mode`","description":"点击选择模式切换按钮时触发","arguments":[{"name":"mode","type":"de"},{"name":"boolean"}]},{"name":"`toggle-theme`","description":"点击主题切换按钮时触发","arguments":[{"name":"theme","type":"me"},{"name":"'light' | 'dark' | 'auto'"}]},{"name":"`create-session`","description":"点击创建新会话时触发","arguments":[]},{"name":"`select-session`","description":"选中某个历史会话时触发","arguments":[{"name":"session","type":"on"},{"name":"OpenCodeWidgetSession"}]},{"name":"`delete-session`","description":"删除某个历史会话时触发","arguments":[{"name":"session","type":"on"},{"name":"OpenCodeWidgetSession"}]},{"name":"`click-selected-node`","description":"点击已选中的气泡或节点卡片时触发","arguments":[{"name":"element","type":"nt"},{"name":"OpenCodeSelectedElement"}]},{"name":"`remove-selected-node`","description":"删除已选中的元素时触发","arguments":[{"name":"payload","type":"ad"},{"name":"OpenCodeRemoveSelectedPayload"}]},{"name":"`clear-selected-nodes`","description":"清空所有选中元素时触发","arguments":[]},{"name":"`empty-action`","description":"点击空状态操作按钮时触发","arguments":[]},{"name":"`frame-loaded`","description":"iframe 加载完成时触发","arguments":[]},{"name":"`thinking-change`","description":"思考状态改变时触发(用于显示加载动画)","arguments":[{"name":"thinking","type":"ng"},{"name":"boolean"}]}],"slots":[{"name":"`button-icon`","description":"自定义触发按钮图标"},{"name":"`session-toggle-icon`","description":"自定义会话列表切换图标"},{"name":"`select-icon`","description":"自定义选择模式切换图标"},{"name":"`close-icon`","description":"自定义关闭按钮图标"},{"name":"`theme-icon`","description":"自定义主题切换图标"},{"name":"`sessions-empty`","description":"自定义会话列表空状态"},{"name":"`empty-state`","description":"自定义 iframe 空状态"},{"name":"","description":"自定义 iframe 加载状态"},{"name":"","description":"自定义错误状态"},{"name":"","description":"自定义 iframe 内容"}]}],"attributes":[]}},"js-types-syntax":"typescript"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vite-plugin-opencode-assistant/components",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.27",
|
|
4
4
|
"description": "Reusable OpenCode widget components built with Pagoda CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"css-selector-generator": "^3.9.1",
|
|
34
|
-
"@vite-plugin-opencode-assistant/shared": "1.0.
|
|
34
|
+
"@vite-plugin-opencode-assistant/shared": "1.0.27"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@vitejs/plugin-vue": "^6.0.5",
|