@vite-plugin-opencode-assistant/components 1.0.10 → 1.0.12

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.
Files changed (35) hide show
  1. package/es/index.d.ts +1 -1
  2. package/es/index.js +1 -1
  3. package/es/open-code-widget/composables/use-widget.d.ts +4 -0
  4. package/es/open-code-widget/composables/use-widget.js +40 -3
  5. package/es/open-code-widget/src/components/Frame.vue.js +52 -2
  6. package/es/open-code-widget/src/components/Header-sfc.css +1 -1
  7. package/es/open-code-widget/src/components/Header.vue.d.ts +4 -2
  8. package/es/open-code-widget/src/components/Header.vue.js +87 -13
  9. package/es/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  10. package/es/open-code-widget/src/components/SessionList-sfc.css +1 -1
  11. package/es/open-code-widget/src/context.d.ts +2 -0
  12. package/es/open-code-widget/src/index-sfc.css +1 -1
  13. package/es/open-code-widget/src/index.vue.d.ts +5 -1
  14. package/es/open-code-widget/src/index.vue.js +12 -4
  15. package/es/open-code-widget/src/types.d.ts +2 -0
  16. package/lib/@vite-plugin-opencode-assistant/components.cjs.js +207 -53
  17. package/lib/@vite-plugin-opencode-assistant/components.es.js +208 -54
  18. package/lib/components.css +4 -4
  19. package/lib/index.d.ts +1 -1
  20. package/lib/index.js +1 -1
  21. package/lib/open-code-widget/composables/use-widget.d.ts +4 -0
  22. package/lib/open-code-widget/composables/use-widget.js +39 -2
  23. package/lib/open-code-widget/src/components/Frame.vue.js +69 -21
  24. package/lib/open-code-widget/src/components/Header-sfc.css +1 -1
  25. package/lib/open-code-widget/src/components/Header.vue.d.ts +4 -2
  26. package/lib/open-code-widget/src/components/Header.vue.js +102 -28
  27. package/lib/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  28. package/lib/open-code-widget/src/components/SessionList-sfc.css +1 -1
  29. package/lib/open-code-widget/src/context.d.ts +2 -0
  30. package/lib/open-code-widget/src/index-sfc.css +1 -1
  31. package/lib/open-code-widget/src/index.vue.d.ts +5 -1
  32. package/lib/open-code-widget/src/index.vue.js +12 -4
  33. package/lib/open-code-widget/src/types.d.ts +2 -0
  34. package/lib/web-types.json +1 -1
  35. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createVNode, defineComponent, inject, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
1
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createVNode, defineComponent, inject, normalizeClass, normalizeStyle, onMounted, onUnmounted, openBlock, provide, ref, renderList, renderSlot, toDisplayString, toRef, useSlots, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
2
2
  //#region es/open-code-widget/src/context.js
3
3
  var CONTEXT_KEY = /* @__PURE__ */ Symbol("OpenCodeWidgetContext");
4
4
  function provideOpenCodeWidgetContext(context) {
@@ -11,18 +11,68 @@ function useOpenCodeWidgetContext() {
11
11
  }
12
12
  //#endregion
13
13
  //#region es/open-code-widget/src/components/Frame.vue.js
14
+ var __defProp$1 = Object.defineProperty;
15
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
16
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
17
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
18
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value
23
+ }) : obj[key] = value;
24
+ var __spreadValues$1 = (a, b) => {
25
+ for (var prop in b || (b = {})) if (__hasOwnProp$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
26
+ if (__getOwnPropSymbols$1) {
27
+ for (var prop of __getOwnPropSymbols$1(b)) if (__propIsEnum$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
28
+ }
29
+ return a;
30
+ };
14
31
  var __vue_sfc__$7 = /* @__PURE__ */ defineComponent({
15
32
  __name: "Frame",
16
33
  setup(__props, { expose: __expose }) {
17
34
  __expose();
18
- const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction } = useOpenCodeWidgetContext();
35
+ const iframeRef = ref(null);
36
+ const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, theme, resolvedTheme } = useOpenCodeWidgetContext();
37
+ const iframeReady = ref(false);
38
+ function sendMessageToIframe(type, data) {
39
+ var _a;
40
+ if (!((_a = iframeRef.value) == null ? void 0 : _a.contentWindow)) return;
41
+ iframeRef.value.contentWindow.postMessage(__spreadValues$1({ type }, data), "*");
42
+ }
43
+ function syncIframeTheme() {
44
+ sendMessageToIframe("OPENCODE_SET_THEME", { theme: resolvedTheme.value });
45
+ }
46
+ function handleIframeMessage(event) {
47
+ var _a;
48
+ if (((_a = event.data) == null ? void 0 : _a.type) === "OPENCODE_READY") syncIframeTheme();
49
+ }
50
+ watch([theme, resolvedTheme], () => {
51
+ syncIframeTheme();
52
+ });
53
+ onMounted(() => {
54
+ if (iframeRef.value) iframeRef.value.addEventListener("load", () => {
55
+ iframeReady.value = true;
56
+ });
57
+ window.addEventListener("message", handleIframeMessage);
58
+ });
59
+ onUnmounted(() => {
60
+ window.removeEventListener("message", handleIframeMessage);
61
+ });
19
62
  const __returned__ = {
63
+ iframeRef,
20
64
  loading,
21
65
  showEmptyState,
22
66
  iframeSrc,
23
67
  emptyStateText,
24
68
  emptyStateActionText,
25
- handleEmptyAction
69
+ handleEmptyAction,
70
+ theme,
71
+ resolvedTheme,
72
+ iframeReady,
73
+ sendMessageToIframe,
74
+ syncIframeTheme,
75
+ handleIframeMessage
26
76
  };
27
77
  Object.defineProperty(__returned__, "__isScriptSetup", {
28
78
  enumerable: false,
@@ -59,6 +109,7 @@ function __vue_render__$7(_ctx, _cache, $props, $setup, $data, $options) {
59
109
  ])], 2),
60
110
  createElementVNode("div", { class: normalizeClass(["opencode-loading-overlay", { visible: $setup.loading }]) }, [renderSlot(_ctx.$slots, "loading", {}, () => [_cache[2] || (_cache[2] = createElementVNode("div", { class: "opencode-loading-spinner" }, null, -1)), _cache[3] || (_cache[3] = createElementVNode("div", { class: "opencode-loading-text" }, "加载中...", -1))])], 2),
61
111
  renderSlot(_ctx.$slots, "content", {}, () => [createElementVNode("iframe", {
112
+ ref: "iframeRef",
62
113
  class: "opencode-iframe",
63
114
  src: $setup.iframeSrc,
64
115
  allow: "clipboard-write; clipboard-read",
@@ -74,16 +125,33 @@ var __vue_sfc__$6 = /* @__PURE__ */ defineComponent({
74
125
  __name: "Header",
75
126
  setup(__props, { expose: __expose }) {
76
127
  __expose();
77
- const { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, handleToggleSessionList, handleToggleSelectMode, handleClose } = useOpenCodeWidgetContext();
128
+ const { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, theme, resolvedTheme, handleToggleSessionList, handleToggleSelectMode, handleToggleTheme, handleClose } = useOpenCodeWidgetContext();
78
129
  const __returned__ = {
79
130
  title,
80
131
  sessionListTitle,
81
132
  sessionListCollapsed,
82
133
  selectMode,
83
134
  selectEnabled,
135
+ theme,
136
+ resolvedTheme,
84
137
  handleToggleSessionList,
85
138
  handleToggleSelectMode,
86
- handleClose
139
+ handleToggleTheme,
140
+ handleClose,
141
+ themeIconTitle: computed(() => {
142
+ return `\u4E3B\u9898: ${{
143
+ auto: "自动",
144
+ light: "亮色",
145
+ dark: "暗色"
146
+ }[theme.value]} (${resolvedTheme.value})`;
147
+ }),
148
+ themeIconLabel: computed(() => {
149
+ return `\u5207\u6362\u4E3B\u9898 - \u5F53\u524D: ${{
150
+ auto: "自动跟随系统",
151
+ light: "亮色主题",
152
+ dark: "暗色主题"
153
+ }[theme.value]}`;
154
+ })
87
155
  };
88
156
  Object.defineProperty(__returned__, "__isScriptSetup", {
89
157
  enumerable: false,
@@ -100,56 +168,97 @@ var _hoisted_3$4 = [
100
168
  "aria-expanded"
101
169
  ];
102
170
  var _hoisted_4$4 = ["aria-pressed", "disabled"];
103
- var _hoisted_5$4 = { class: "opencode-chat-header-title" };
104
- var _hoisted_6$3 = { class: "opencode-chat-header-actions" };
171
+ var _hoisted_5$4 = ["title", "aria-label"];
172
+ var _hoisted_6$3 = {
173
+ key: 0,
174
+ viewBox: "0 0 24 24",
175
+ width: "16",
176
+ height: "16",
177
+ fill: "none",
178
+ stroke: "currentColor",
179
+ "stroke-width": "2",
180
+ "aria-hidden": "true"
181
+ };
182
+ var _hoisted_7$2 = {
183
+ key: 1,
184
+ viewBox: "0 0 24 24",
185
+ width: "16",
186
+ height: "16",
187
+ fill: "none",
188
+ stroke: "currentColor",
189
+ "stroke-width": "2",
190
+ "aria-hidden": "true"
191
+ };
192
+ var _hoisted_8$2 = {
193
+ key: 2,
194
+ viewBox: "0 0 24 24",
195
+ width: "16",
196
+ height: "16",
197
+ fill: "none",
198
+ stroke: "currentColor",
199
+ "stroke-width": "2",
200
+ "aria-hidden": "true"
201
+ };
202
+ var _hoisted_9$1 = { class: "opencode-chat-header-title" };
203
+ var _hoisted_10 = { class: "opencode-chat-header-actions" };
105
204
  function __vue_render__$6(_ctx, _cache, $props, $setup, $data, $options) {
106
205
  return openBlock(), createElementBlock("div", _hoisted_1$6, [
107
- createElementVNode("div", _hoisted_2$4, [createElementVNode("button", {
108
- class: "opencode-header-btn session-toggle",
109
- type: "button",
110
- title: $setup.sessionListTitle,
111
- "aria-label": $setup.sessionListTitle,
112
- "aria-expanded": !$setup.sessionListCollapsed,
113
- onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
114
- }, [renderSlot(_ctx.$slots, "session-toggle-icon", {}, () => [_cache[3] || (_cache[3] = createElementVNode("svg", {
115
- viewBox: "0 0 24 24",
116
- width: "16",
117
- height: "16",
118
- fill: "none",
119
- stroke: "currentColor",
120
- "stroke-width": "2",
121
- "aria-hidden": "true"
122
- }, [createElementVNode("path", {
123
- d: "M4 6h16M4 12h16M4 18h16",
124
- "stroke-linecap": "round"
125
- })], -1))])], 8, _hoisted_3$4), createElementVNode("button", {
126
- class: normalizeClass(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
127
- type: "button",
128
- title: "选择页面元素 (Ctrl+P)",
129
- "aria-label": "选择页面元素",
130
- "aria-pressed": $setup.selectMode,
131
- disabled: !$setup.selectEnabled,
132
- onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
133
- }, [renderSlot(_ctx.$slots, "select-icon", {}, () => [_cache[4] || (_cache[4] = createElementVNode("svg", {
134
- viewBox: "0 0 1024 1024",
135
- width: "16",
136
- height: "16",
137
- "aria-hidden": "true"
138
- }, [createElementVNode("path", {
139
- fill: "currentColor",
140
- d: "M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768m0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896"
141
- }), createElementVNode("path", {
142
- fill: "currentColor",
143
- d: "M512 96a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V128a32 32 0 0 1 32-32m0 576a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V704a32 32 0 0 1 32-32M96 512a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H128a32 32 0 0 1-32-32m576 0a32 32 0 0 1 32-32h192a32 32 0 1 1 0 64H704a32 32 0 0 1-32-32"
144
- })], -1))])], 10, _hoisted_4$4)]),
145
- createElementVNode("span", _hoisted_5$4, toDisplayString($setup.title), 1),
146
- createElementVNode("div", _hoisted_6$3, [createElementVNode("button", {
206
+ createElementVNode("div", _hoisted_2$4, [
207
+ createElementVNode("button", {
208
+ class: normalizeClass(["opencode-header-btn session-toggle", { active: !$setup.sessionListCollapsed }]),
209
+ type: "button",
210
+ title: $setup.sessionListTitle,
211
+ "aria-label": $setup.sessionListTitle,
212
+ "aria-expanded": !$setup.sessionListCollapsed,
213
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
214
+ }, [renderSlot(_ctx.$slots, "session-toggle-icon", {}, () => [_cache[4] || (_cache[4] = createElementVNode("svg", {
215
+ viewBox: "0 0 24 24",
216
+ width: "16",
217
+ height: "16",
218
+ fill: "none",
219
+ stroke: "currentColor",
220
+ "stroke-width": "2",
221
+ "aria-hidden": "true"
222
+ }, [createElementVNode("path", {
223
+ d: "M4 6h16M4 12h16M4 18h16",
224
+ "stroke-linecap": "round"
225
+ })], -1))])], 10, _hoisted_3$4),
226
+ createElementVNode("button", {
227
+ class: normalizeClass(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
228
+ type: "button",
229
+ title: "选择页面元素 (Ctrl+P)",
230
+ "aria-label": "选择页面元素",
231
+ "aria-pressed": $setup.selectMode,
232
+ disabled: !$setup.selectEnabled,
233
+ onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
234
+ }, [renderSlot(_ctx.$slots, "select-icon", {}, () => [_cache[5] || (_cache[5] = createElementVNode("svg", {
235
+ viewBox: "0 0 1024 1024",
236
+ width: "16",
237
+ height: "16",
238
+ "aria-hidden": "true"
239
+ }, [createElementVNode("path", {
240
+ fill: "currentColor",
241
+ d: "M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768m0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896"
242
+ }), createElementVNode("path", {
243
+ fill: "currentColor",
244
+ d: "M512 96a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V128a32 32 0 0 1 32-32m0 576a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V704a32 32 0 0 1 32-32M96 512a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H128a32 32 0 0 1-32-32m576 0a32 32 0 0 1 32-32h192a32 32 0 1 1 0 64H704a32 32 0 0 1-32-32"
245
+ })], -1))])], 10, _hoisted_4$4),
246
+ createElementVNode("button", {
247
+ class: "opencode-header-btn theme-btn",
248
+ type: "button",
249
+ title: $setup.themeIconTitle,
250
+ "aria-label": $setup.themeIconLabel,
251
+ onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleToggleTheme && $setup.handleToggleTheme(...args))
252
+ }, [renderSlot(_ctx.$slots, "theme-icon", {}, () => [$setup.theme === "light" ? (openBlock(), createElementBlock("svg", _hoisted_6$3, [..._cache[6] || (_cache[6] = [createStaticVNode("<circle cx=\"12\" cy=\"12\" r=\"5\"></circle><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"></line><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"></line><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"></line><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"></line><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"></line><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"></line>", 9)])])) : $setup.theme === "dark" ? (openBlock(), createElementBlock("svg", _hoisted_7$2, [..._cache[7] || (_cache[7] = [createElementVNode("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }, null, -1)])])) : (openBlock(), createElementBlock("svg", _hoisted_8$2, [..._cache[8] || (_cache[8] = [createStaticVNode("<rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"></line><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"></line><circle cx=\"12\" cy=\"10\" r=\"3\"></circle><path d=\"M7 7l2 2M17 7l-2 2M7 13l2-2M17 13l-2-2\"></path>", 5)])]))])], 8, _hoisted_5$4)
253
+ ]),
254
+ createElementVNode("span", _hoisted_9$1, toDisplayString($setup.title), 1),
255
+ createElementVNode("div", _hoisted_10, [createElementVNode("button", {
147
256
  class: "opencode-header-btn close",
148
257
  type: "button",
149
258
  title: "关闭",
150
259
  "aria-label": "关闭面板",
151
- onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleClose && $setup.handleClose(...args))
152
- }, [renderSlot(_ctx.$slots, "close-icon", {}, () => [_cache[5] || (_cache[5] = createElementVNode("svg", {
260
+ onClick: _cache[3] || (_cache[3] = (...args) => $setup.handleClose && $setup.handleClose(...args))
261
+ }, [renderSlot(_ctx.$slots, "close-icon", {}, () => [_cache[9] || (_cache[9] = createElementVNode("svg", {
153
262
  viewBox: "0 0 24 24",
154
263
  width: "14",
155
264
  height: "14",
@@ -650,11 +759,39 @@ function useSession(options) {
650
759
  }
651
760
  //#endregion
652
761
  //#region es/open-code-widget/composables/use-widget.js
762
+ var THEME_CYCLE = [
763
+ "auto",
764
+ "light",
765
+ "dark"
766
+ ];
653
767
  function useWidget(options) {
768
+ const systemTheme = ref("light");
769
+ function getSystemTheme() {
770
+ if (typeof window === "undefined") return "light";
771
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
772
+ }
773
+ let mediaQuery = null;
774
+ let handleChange = null;
775
+ onMounted(() => {
776
+ if (typeof window === "undefined") return;
777
+ systemTheme.value = getSystemTheme();
778
+ mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
779
+ handleChange = (e) => {
780
+ systemTheme.value = e.matches ? "dark" : "light";
781
+ };
782
+ mediaQuery.addEventListener("change", handleChange);
783
+ });
784
+ onUnmounted(() => {
785
+ if (mediaQuery && handleChange) mediaQuery.removeEventListener("change", handleChange);
786
+ });
787
+ const resolvedTheme = computed(() => {
788
+ if (options.theme.value === "auto") return systemTheme.value;
789
+ return options.theme.value;
790
+ });
654
791
  const containerClasses = computed(() => [
655
792
  "opencode-widget",
656
793
  options.position.value,
657
- `opencode-theme-${options.theme.value}`
794
+ `opencode-theme-${resolvedTheme.value}`
658
795
  ]);
659
796
  const buttonActive = computed(() => !!(options.open.value || options.selectMode.value));
660
797
  const iframeSource = computed(() => options.iframeSrc.value || "about:blank");
@@ -677,15 +814,22 @@ function useWidget(options) {
677
814
  function handleEmptyAction() {
678
815
  options.onEmptyAction();
679
816
  }
817
+ function handleToggleTheme() {
818
+ var _a;
819
+ const nextTheme = THEME_CYCLE[(THEME_CYCLE.indexOf(options.theme.value) + 1) % THEME_CYCLE.length];
820
+ (_a = options.onToggleTheme) == null || _a.call(options, nextTheme);
821
+ }
680
822
  return {
681
823
  buttonActive,
682
824
  containerClasses,
683
825
  iframeSource,
684
826
  sessionListTitle,
827
+ resolvedTheme,
685
828
  handleClose,
686
829
  handleEmptyAction,
687
830
  handleToggle,
688
- handleToggleSessionList
831
+ handleToggleSessionList,
832
+ handleToggleTheme
689
833
  };
690
834
  }
691
835
  //#endregion
@@ -899,7 +1043,7 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
899
1043
  theme: {
900
1044
  type: String,
901
1045
  required: false,
902
- default: "light"
1046
+ default: "auto"
903
1047
  },
904
1048
  title: {
905
1049
  type: String,
@@ -992,10 +1136,12 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
992
1136
  "update:sessionListCollapsed",
993
1137
  "update:currentSessionId",
994
1138
  "update:selectedElements",
1139
+ "update:theme",
995
1140
  "toggle",
996
1141
  "close",
997
1142
  "toggle-session-list",
998
1143
  "toggle-select-mode",
1144
+ "toggle-theme",
999
1145
  "create-session",
1000
1146
  "select-session",
1001
1147
  "delete-session",
@@ -1045,7 +1191,7 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1045
1191
  watch(() => props.sessionListCollapsed, (val) => {
1046
1192
  localSessionListCollapsed.value = val;
1047
1193
  });
1048
- const { buttonActive, containerClasses, iframeSource, sessionListTitle, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList } = useWidget({
1194
+ const { buttonActive, containerClasses, iframeSource, sessionListTitle, resolvedTheme, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList, handleToggleTheme } = useWidget({
1049
1195
  position: toRef(props, "position"),
1050
1196
  theme: toRef(props, "theme"),
1051
1197
  open: toRef(props, "open"),
@@ -1071,6 +1217,10 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1071
1217
  },
1072
1218
  onEmptyAction: () => {
1073
1219
  emit("empty-action");
1220
+ },
1221
+ onToggleTheme: (newTheme) => {
1222
+ emit("update:theme", newTheme);
1223
+ emit("toggle-theme", newTheme);
1074
1224
  }
1075
1225
  });
1076
1226
  const { sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession } = useSession({
@@ -1115,6 +1265,7 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1115
1265
  });
1116
1266
  provideOpenCodeWidgetContext({
1117
1267
  theme: toRef(props, "theme"),
1268
+ resolvedTheme,
1118
1269
  title: toRef(props, "title"),
1119
1270
  hotkeyLabel: toRef(props, "hotkeyLabel"),
1120
1271
  selectShortcutLabel: toRef(props, "selectShortcutLabel"),
@@ -1139,6 +1290,7 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1139
1290
  handleToggle,
1140
1291
  handleClose,
1141
1292
  handleToggleSessionList,
1293
+ handleToggleTheme,
1142
1294
  handleEmptyAction,
1143
1295
  handleCreateSession,
1144
1296
  handleSelectSession,
@@ -1177,10 +1329,12 @@ var __vue_sfc__ = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({
1177
1329
  containerClasses,
1178
1330
  iframeSource,
1179
1331
  sessionListTitle,
1332
+ resolvedTheme,
1180
1333
  handleClose,
1181
1334
  handleEmptyAction,
1182
1335
  handleToggle,
1183
1336
  handleToggleSessionList,
1337
+ handleToggleTheme,
1184
1338
  sessionItems,
1185
1339
  handleCreateSession,
1186
1340
  handleDeleteSession,
@@ -1311,7 +1465,7 @@ __vue_sfc__.render = __vue_render__;
1311
1465
  var open_code_widget_default = __vue_sfc__;
1312
1466
  //#endregion
1313
1467
  //#region es/index.js
1314
- var version = "1.0.10";
1468
+ var version = "1.0.12";
1315
1469
  function install(app, options) {
1316
1470
  [open_code_widget_default].forEach((item) => {
1317
1471
  if (item.install) app.use(item, options);
@@ -1,9 +1,9 @@
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-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: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--oc-trigger-bg-hover: linear-gradient(135deg, #764ba2 0%, #667eea 100%);--oc-trigger-bg-active: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);--oc-trigger-shadow: 0 4px 15px rgba(102, 126, 234, .4);--oc-trigger-shadow-hover: 0 6px 20px rgba(102, 126, 234, .6);--oc-trigger-shadow-active: 0 6px 20px rgba(240, 147, 251, .4);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-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: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--oc-trigger-bg-hover: linear-gradient(135deg, #764ba2 0%, #667eea 100%);--oc-trigger-bg-active: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);--oc-trigger-shadow: 0 4px 15px rgba(102, 126, 234, .5);--oc-trigger-shadow-hover: 0 6px 20px rgba(102, 126, 234, .7);--oc-trigger-shadow-active: 0 6px 20px rgba(240, 147, 251, .5)}.opencode-widget.bottom-right{bottom:20px;right:20px}.opencode-widget.bottom-left{bottom:20px;left:20px}.opencode-widget.top-right{top:20px;right:20px}.opencode-widget.top-left{top:20px;left:20px}.opencode-chat{position:absolute;width:700px;height:86vh;background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translateY(20px) scale(.95);transition:all .3s ease;display:flex;flex-direction:column}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-widget.bottom-right .opencode-chat{bottom:56px;right:0}.opencode-widget.bottom-left .opencode-chat{bottom:56px;left:0}.opencode-widget.top-right .opencode-chat{top:56px;right:0}.opencode-widget.top-left .opencode-chat{top:56px;left:0}.opencode-widget.bottom-right .opencode-selected-bubbles{bottom:56px;right:0}.opencode-widget.bottom-left .opencode-selected-bubbles{bottom:56px;left:0}.opencode-widget.top-right .opencode-selected-bubbles{top:56px;bottom:auto;right:0}.opencode-widget.top-left .opencode-selected-bubbles{top:56px;bottom:auto;left:0}.opencode-chat.open{opacity:1;visibility:visible;transform:translateY(0) scale(1)}.opencode-notification{position:absolute;top:20px;left:50%;transform:translate(-50%);padding:12px 20px;background:var(--oc-bg-main);color:var(--oc-text-primary);border:1px solid var(--oc-border-primary);border-radius:8px;font-size:14px;box-shadow:var(--oc-shadow-lg);animation:slideDown .3s ease;z-index:10000000}.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-element-highlight{position:fixed;pointer-events:none;z-index:999998;display:none;transition:all .1s ease;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;display:none;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
+ .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-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: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--oc-trigger-bg-hover: linear-gradient(135deg, #764ba2 0%, #667eea 100%);--oc-trigger-bg-active: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);--oc-trigger-shadow: 0 4px 15px rgba(102, 126, 234, .4);--oc-trigger-shadow-hover: 0 6px 20px rgba(102, 126, 234, .6);--oc-trigger-shadow-active: 0 6px 20px rgba(240, 147, 251, .4);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-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: linear-gradient(135deg, #667eea 0%, #764ba2 100%);--oc-trigger-bg-hover: linear-gradient(135deg, #764ba2 0%, #667eea 100%);--oc-trigger-bg-active: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);--oc-trigger-shadow: 0 4px 15px rgba(102, 126, 234, .5);--oc-trigger-shadow-hover: 0 6px 20px rgba(102, 126, 234, .7);--oc-trigger-shadow-active: 0 6px 20px rgba(240, 147, 251, .5)}.opencode-widget.bottom-right{bottom:20px;right:20px}.opencode-widget.bottom-left{bottom:20px;left:20px}.opencode-widget.top-right{top:20px;right:20px}.opencode-widget.top-left{top:20px;left:20px}.opencode-chat{position:absolute;width:700px;height:86vh;background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translateY(20px) scale(.95);transition:all .3s ease;display:flex;flex-direction:column}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-widget.bottom-right .opencode-chat{bottom:56px;right:0}.opencode-widget.bottom-left .opencode-chat{bottom:56px;left:0}.opencode-widget.top-right .opencode-chat{top:56px;right:0}.opencode-widget.top-left .opencode-chat{top:56px;left:0}.opencode-widget.bottom-right .opencode-selected-bubbles{bottom:56px;right:0}.opencode-widget.bottom-left .opencode-selected-bubbles{bottom:56px;left:0}.opencode-widget.top-right .opencode-selected-bubbles{top:56px;bottom:auto;right:0}.opencode-widget.top-left .opencode-selected-bubbles{top:56px;bottom:auto;left:0}.opencode-chat.open{opacity:1;visibility:visible;transform:translateY(0) scale(1)}.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-element-highlight{position:fixed;pointer-events:none;z-index:999998;display:none;transition:all .1s ease;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;display:none;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)}}
2
2
  .opencode-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;margin-top:-42px}.opencode-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:10;transition:opacity .3s ease}.opencode-loading-overlay.visible{display:flex}.opencode-loading-spinner{width:40px;height:40px;border:3px solid var(--oc-border-primary);border-top-color:var(--oc-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.opencode-loading-text{margin-top:12px;font-size:14px;color:var(--oc-text-placeholder)}.opencode-empty-state-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-bg-secondary);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:5;transition:opacity .3s ease;margin-top:42px}.opencode-empty-state-overlay.visible{display:flex}.opencode-empty-state-icon{color:var(--oc-text-placeholder);margin-bottom:16px}.opencode-empty-state-text{color:var(--oc-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.opencode-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--oc-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--oc-shadow-primary)}.opencode-empty-state-btn:hover{background:var(--oc-primary-hover);transform:translateY(-1px);box-shadow:var(--oc-shadow-primary-hover)}.opencode-empty-state-btn:active{transform:translateY(0)}.opencode-iframe{width:100%;height:100%;border:none}
3
- .opencode-chat-header{position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;padding:0 12px;height:40px;background:var(--oc-bg-secondary);border-bottom:1px solid var(--oc-border-primary);z-index:5}.opencode-chat-header-left{display:flex;align-items:center;gap:4px}.opencode-chat-header-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);position:absolute;left:50%;transform:translate(-50%)}.opencode-chat-header-actions{display:flex;gap:4px}.opencode-header-btn{width:28px;height:28px;border-radius:6px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-header-btn:hover{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-header-btn.close:hover{background:var(--oc-danger);color:#fff}.opencode-header-btn.select-btn.active{background:var(--oc-primary);color:#fff}
4
- .opencode-select-mode-hint{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:10px 16px;background:var(--oc-danger);color:#fff;border-radius:8px;font-size:13px;box-shadow:var(--oc-shadow-danger);z-index:9999999;display:none;align-items:center;gap:12px}.opencode-select-mode-hint.visible{display:flex;animation:slideDown .3s ease}.opencode-hint-shortcut{padding:2px 6px;background:rgba(255,255,255,.2);border-radius:4px;font-size:12px}
3
+ .opencode-chat-header{position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;padding:0 12px;height:40px;background:var(--oc-bg-secondary);border-bottom:1px solid var(--oc-border-primary);z-index:5}.opencode-chat-header-left{display:flex;align-items:center;gap:4px}.opencode-chat-header-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);position:absolute;left:50%;transform:translate(-50%)}.opencode-chat-header-actions{display:flex;gap:4px}.opencode-header-btn{width:28px;height:28px;border-radius:6px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-header-btn:hover{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-header-btn.close:hover{background:var(--oc-danger);color:#fff}.opencode-header-btn.select-btn.active,.opencode-header-btn.session-toggle.active{background:var(--oc-primary);color:#fff}
4
+ .opencode-select-mode-hint{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:14px 20px;background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;border-radius:12px;font-size:15px;font-weight:500;box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3);z-index:9999999;display:none;align-items:center;gap:12px;border:2px solid rgba(255,255,255,.3)}.opencode-select-mode-hint.visible{display:flex;animation:slideDown .3s ease,pulseHint 2s ease-in-out infinite}.opencode-hint-shortcut{padding:4px 10px;background:rgba(255,255,255,.25);border-radius:6px;font-size:13px;font-weight:600;border:1px solid rgba(255,255,255,.4)}@keyframes pulseHint{0%,to{box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3)}50%{box-shadow:0 6px 20px rgba(239,68,68,.6),0 0 0 6px rgba(239,68,68,.4)}}
5
5
  .opencode-selected-bubbles{position:absolute;display:none;flex-direction:column;gap:6px;max-width:220px;max-height:300px;overflow-y:auto}.opencode-selected-bubbles.visible{display:flex}.opencode-selected-bubble{display:flex;flex-direction:column;gap:2px;padding:8px 24px 8px 10px;background:var(--oc-bg-main);border:1px solid var(--oc-border-primary);border-radius:8px;font-size:12px;box-shadow:var(--oc-shadow-sm);position:relative;cursor:pointer;transition:all .2s}.opencode-selected-bubble:hover{border-color:var(--oc-primary);box-shadow:var(--oc-shadow-primary)}.opencode-bubble-text{color:var(--oc-text-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-bubble-file{color:var(--oc-text-placeholder);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-bubble-remove{position:absolute;top:8px;right:6px;width:16px;height:16px;border-radius:50%;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:12px;transition:all .2s}.opencode-bubble-remove:hover{background:var(--oc-danger);color:#fff}.opencode-bubble-empty{padding:8px 12px;background:var(--oc-bg-main);border:1px dashed var(--oc-border-secondary);border-radius:8px;color:var(--oc-text-placeholder);font-size:12px;text-align:center}
6
6
  .opencode-right-toolbar{width:140px;background:var(--oc-bg-secondary);border-left:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease;overflow:hidden}.opencode-right-toolbar.collapsed{width:0;overflow:hidden}.opencode-right-toolbar.collapsed .opencode-selected-nodes-header,.opencode-right-toolbar.collapsed .opencode-selected-nodes,.opencode-right-toolbar.collapsed .opencode-clear-all-btn{display:none}.opencode-selected-nodes-header{padding:12px 8px 8px;border-bottom:1px solid var(--oc-border-primary)}.opencode-selected-nodes-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);margin-bottom:4px}.opencode-selected-nodes-desc{font-size:11px;color:var(--oc-text-placeholder);line-height:1.4}.opencode-selected-nodes{flex:1;display:flex;flex-direction:column;padding:8px;gap:6px;overflow-y:auto;overflow-x:hidden}.opencode-selected-nodes:empty:before{content:"\6682\65e0\9009\4e2d\5143\7d20";color:var(--oc-text-placeholder);font-size:12px;text-align:center;padding:20px 10px}.opencode-selected-node{display:flex;align-items:center;gap:8px;padding:8px 10px;background:var(--oc-bg-main);border:1px solid var(--oc-border-primary);border-radius:6px;font-size:12px;transition:all .2s}.opencode-selected-node:hover{border-color:var(--oc-primary);box-shadow:var(--oc-shadow-primary)}.opencode-node-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.opencode-node-text{color:var(--oc-text-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-node-file{color:var(--oc-text-placeholder);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-node-remove{width:18px;height:18px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;transition:all .2s;flex-shrink:0}.opencode-node-remove:hover{background:var(--oc-danger);color:#fff}.opencode-clear-all-btn{width:calc(100% - 16px);margin:8px;padding:8px 12px;border-radius:6px;border:none;background:var(--oc-danger);color:#fff;font-size:12px;font-weight:500;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .2s}.opencode-clear-all-btn:hover{background:var(--oc-danger-hover);transform:scale(1.02)}
7
- .opencode-session-list{width:240px;background:var(--oc-bg-secondary);border-right:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease}.opencode-session-list.collapsed{width:0;overflow:hidden}.opencode-session-list.collapsed .opencode-session-list-header,.opencode-session-list.collapsed .opencode-session-list-content{display:none}.opencode-session-list-header{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:flex;justify-content:space-between;align-items:center;font-weight:600;font-size:14px;color:var(--oc-text-primary)}.opencode-new-session-btn{width:28px;height:28px;border-radius:6px;border:none;background:var(--oc-primary);color:#fff;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-new-session-btn:hover{background:var(--oc-primary-hover);transform:scale(1.05)}.opencode-session-list-content{flex:1;overflow-y:auto;padding:8px;position:relative}.opencode-session-list-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:10;border-radius:8px}.opencode-loading-spinner.small{width:24px;height:24px;border-width:2px}.opencode-session-item{padding:12px;border-radius:8px;cursor:pointer;transition:all .2s;margin-bottom:4px;color:var(--oc-text-primary)}.opencode-session-item:hover{background:var(--oc-bg-tertiary)}.opencode-session-item.active{background:var(--oc-primary);color:#fff}.opencode-session-title{font-size:14px;font-weight:500;margin-bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-session-meta{font-size:12px;opacity:.6}.opencode-session-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.opencode-session-delete-btn{width:20px;height:20px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s;opacity:0;flex-shrink:0}.opencode-session-item:hover .opencode-session-delete-btn{opacity:1}.opencode-session-delete-btn:hover{background:var(--oc-danger);color:#fff}.opencode-session-item.active .opencode-session-delete-btn{color:rgba(255,255,255,.7)}.opencode-session-item.active .opencode-session-delete-btn:hover{background:rgba(255,255,255,.2);color:#fff}.opencode-session-header-skeleton{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:none;justify-content:space-between;align-items:center}.opencode-session-header-skeleton.visible{display:flex}.opencode-skeleton-header-title{height:18px;width:80px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px}.opencode-skeleton-header-btn{width:28px;height:28px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:6px}.opencode-session-skeleton{flex:1;overflow-y:auto;padding:8px;display:none}.opencode-session-skeleton.visible{display:block}.opencode-skeleton-item{padding:12px;border-radius:8px;margin-bottom:4px;background:var(--oc-skeleton-bg)}.opencode-skeleton-title{height:16px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;margin-bottom:8px;width:70%}.opencode-skeleton-meta{height:12px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;width:50%}.opencode-session-empty{padding:32px 16px;text-align:center;color:var(--oc-text-placeholder);font-size:13px}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}
7
+ .opencode-session-list{width:240px;background:var(--oc-bg-secondary);border-right:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease}.opencode-session-list.collapsed{width:0;overflow:hidden}.opencode-session-list.collapsed .opencode-session-list-header,.opencode-session-list.collapsed .opencode-session-list-content{display:none}.opencode-session-list-header{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:flex;justify-content:space-between;align-items:center;font-weight:600;font-size:14px;color:var(--oc-text-primary)}.opencode-new-session-btn{width:28px;height:28px;border-radius:6px;border:none;background:var(--oc-primary);color:#fff;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-new-session-btn:hover{background:var(--oc-primary-hover);transform:scale(1.05)}.opencode-session-list-content{flex:1;overflow-y:auto;padding:8px;position:relative}.opencode-session-list-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:10;border-radius:8px}.opencode-loading-spinner.small{width:24px;height:24px;border-width:2px}.opencode-session-item{padding:12px;border-radius:8px;cursor:pointer;transition:transform .2s;margin-bottom:4px;color:var(--oc-text-primary)}.opencode-session-item:hover{background:var(--oc-bg-tertiary)}.opencode-session-item.active{background:var(--oc-primary);color:#fff;transition:none}.opencode-session-title{font-size:14px;font-weight:500;margin-bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-session-meta{font-size:12px;opacity:.6}.opencode-session-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.opencode-session-delete-btn{width:20px;height:20px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s;opacity:0;flex-shrink:0}.opencode-session-item:hover .opencode-session-delete-btn{opacity:1}.opencode-session-delete-btn:hover{background:var(--oc-danger);color:#fff}.opencode-session-item.active .opencode-session-delete-btn{color:rgba(255,255,255,.7)}.opencode-session-item.active .opencode-session-delete-btn:hover{background:rgba(255,255,255,.2);color:#fff}.opencode-session-header-skeleton{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:none;justify-content:space-between;align-items:center}.opencode-session-header-skeleton.visible{display:flex}.opencode-skeleton-header-title{height:18px;width:80px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px}.opencode-skeleton-header-btn{width:28px;height:28px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:6px}.opencode-session-skeleton{flex:1;overflow-y:auto;padding:8px;display:none}.opencode-session-skeleton.visible{display:block}.opencode-skeleton-item{padding:12px;border-radius:8px;margin-bottom:4px;background:var(--oc-skeleton-bg)}.opencode-skeleton-title{height:16px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;margin-bottom:8px;width:70%}.opencode-skeleton-meta{height:12px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;width:50%}.opencode-session-empty{padding:32px 16px;text-align:center;color:var(--oc-text-placeholder);font-size:13px}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}
8
8
  .opencode-button{width:44px;height:44px;border-radius:50%;background:var(--oc-trigger-bg);border:none;cursor:pointer;box-shadow:var(--oc-trigger-shadow);transition:all .3s ease;display:flex;align-items:center;justify-content:center;color:#fff;padding:0;position:relative}.opencode-button:before{content:"";position:absolute;top:-8px;left:-8px;right:-8px;bottom:-8px;border-radius:50%}.opencode-button:hover{transform:scale(1.1);box-shadow:var(--oc-trigger-shadow-hover);background:var(--oc-trigger-bg-hover)}.opencode-button.active{background:var(--oc-trigger-bg-active);box-shadow:var(--oc-trigger-shadow-active)}.opencode-button.active svg{transform:rotate(180deg)}.opencode-button svg{transition:transform .3s ease}.opencode-button.loading{animation:pulse 1s infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}
9
9
  /*$vite$:1*/
package/lib/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import OpenCodeWidget from './open-code-widget';
2
2
  import type { App } from 'vue';
3
- declare const version = "1.0.10";
3
+ declare const version = "1.0.12";
4
4
  declare function install(app: App<any>, options?: any): void;
5
5
  export { install, version, OpenCodeWidget };
6
6
  export default install;
package/lib/index.js CHANGED
@@ -34,7 +34,7 @@ __export(lib_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(lib_exports);
36
36
  var import_open_code_widget = __toESM(require("./open-code-widget"));
37
- const version = "1.0.10";
37
+ const version = "1.0.12";
38
38
  function install(app, options) {
39
39
  const components = [
40
40
  import_open_code_widget.default
@@ -1,4 +1,5 @@
1
1
  import { type Ref } from "vue";
2
+ import type { OpenCodeWidgetTheme } from "../src/types";
2
3
  export interface UseWidgetOptions {
3
4
  position: Ref<string>;
4
5
  theme: Ref<string>;
@@ -11,14 +12,17 @@ export interface UseWidgetOptions {
11
12
  onClose: () => void;
12
13
  onToggleSessionList: (collapsed: boolean) => void;
13
14
  onEmptyAction: () => void;
15
+ onToggleTheme?: (theme: OpenCodeWidgetTheme) => void;
14
16
  }
15
17
  export declare function useWidget(options: UseWidgetOptions): {
16
18
  buttonActive: import("vue").ComputedRef<boolean>;
17
19
  containerClasses: import("vue").ComputedRef<string[]>;
18
20
  iframeSource: import("vue").ComputedRef<string>;
19
21
  sessionListTitle: import("vue").ComputedRef<"展开会话列表" | "折叠会话列表">;
22
+ resolvedTheme: import("vue").ComputedRef<"light" | "dark">;
20
23
  handleClose: () => void;
21
24
  handleEmptyAction: () => void;
22
25
  handleToggle: () => void;
23
26
  handleToggleSessionList: () => void;
27
+ handleToggleTheme: () => void;
24
28
  };
@@ -21,11 +21,39 @@ __export(use_widget_exports, {
21
21
  });
22
22
  module.exports = __toCommonJS(use_widget_exports);
23
23
  var import_vue = require("vue");
24
+ const THEME_CYCLE = ["auto", "light", "dark"];
24
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
+ });
25
53
  const containerClasses = (0, import_vue.computed)(() => [
26
54
  "opencode-widget",
27
55
  options.position.value,
28
- `opencode-theme-${options.theme.value}`
56
+ `opencode-theme-${resolvedTheme.value}`
29
57
  ]);
30
58
  const buttonActive = (0, import_vue.computed)(() => !!(options.open.value || options.selectMode.value));
31
59
  const iframeSource = (0, import_vue.computed)(() => options.iframeSrc.value || "about:blank");
@@ -50,14 +78,23 @@ function useWidget(options) {
50
78
  function handleEmptyAction() {
51
79
  options.onEmptyAction();
52
80
  }
81
+ function handleToggleTheme() {
82
+ var _a;
83
+ const currentIndex = THEME_CYCLE.indexOf(options.theme.value);
84
+ const nextIndex = (currentIndex + 1) % THEME_CYCLE.length;
85
+ const nextTheme = THEME_CYCLE[nextIndex];
86
+ (_a = options.onToggleTheme) == null ? void 0 : _a.call(options, nextTheme);
87
+ }
53
88
  return {
54
89
  buttonActive,
55
90
  containerClasses,
56
91
  iframeSource,
57
92
  sessionListTitle,
93
+ resolvedTheme,
58
94
  handleClose,
59
95
  handleEmptyAction,
60
96
  handleToggle,
61
- handleToggleSessionList
97
+ handleToggleSessionList,
98
+ handleToggleTheme
62
99
  };
63
100
  }