@vite-plugin-opencode-assistant/components 1.0.11 → 1.0.13

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 (37) 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-inspector.js +34 -4
  4. package/es/open-code-widget/composables/use-widget.d.ts +4 -0
  5. package/es/open-code-widget/composables/use-widget.js +40 -3
  6. package/es/open-code-widget/src/components/Frame.vue.js +52 -2
  7. package/es/open-code-widget/src/components/Header-sfc.css +1 -1
  8. package/es/open-code-widget/src/components/Header.vue.d.ts +4 -2
  9. package/es/open-code-widget/src/components/Header.vue.js +87 -13
  10. package/es/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  11. package/es/open-code-widget/src/components/SessionList-sfc.css +1 -1
  12. package/es/open-code-widget/src/context.d.ts +2 -0
  13. package/es/open-code-widget/src/index-sfc.css +1 -1
  14. package/es/open-code-widget/src/index.vue.d.ts +5 -1
  15. package/es/open-code-widget/src/index.vue.js +12 -4
  16. package/es/open-code-widget/src/types.d.ts +2 -0
  17. package/lib/@vite-plugin-opencode-assistant/components.cjs.js +239 -57
  18. package/lib/@vite-plugin-opencode-assistant/components.es.js +240 -58
  19. package/lib/components.css +4 -4
  20. package/lib/index.d.ts +1 -1
  21. package/lib/index.js +1 -1
  22. package/lib/open-code-widget/composables/use-inspector.js +34 -4
  23. package/lib/open-code-widget/composables/use-widget.d.ts +4 -0
  24. package/lib/open-code-widget/composables/use-widget.js +39 -2
  25. package/lib/open-code-widget/src/components/Frame.vue.js +69 -21
  26. package/lib/open-code-widget/src/components/Header-sfc.css +1 -1
  27. package/lib/open-code-widget/src/components/Header.vue.d.ts +4 -2
  28. package/lib/open-code-widget/src/components/Header.vue.js +102 -28
  29. package/lib/open-code-widget/src/components/SelectHint-sfc.css +1 -1
  30. package/lib/open-code-widget/src/components/SessionList-sfc.css +1 -1
  31. package/lib/open-code-widget/src/context.d.ts +2 -0
  32. package/lib/open-code-widget/src/index-sfc.css +1 -1
  33. package/lib/open-code-widget/src/index.vue.d.ts +5 -1
  34. package/lib/open-code-widget/src/index.vue.js +12 -4
  35. package/lib/open-code-widget/src/types.d.ts +2 -0
  36. package/lib/web-types.json +1 -1
  37. package/package.json +1 -1
@@ -42,10 +42,12 @@ export type OpenCodeWidgetEmits = {
42
42
  (e: "update:sessionListCollapsed", value: boolean): void;
43
43
  (e: "update:currentSessionId", value: string | null): void;
44
44
  (e: "update:selectedElements", value: OpenCodeSelectedElement[]): void;
45
+ (e: "update:theme", value: OpenCodeWidgetTheme): void;
45
46
  (e: "toggle", value: boolean): void;
46
47
  (e: "close"): void;
47
48
  (e: "toggle-session-list", value: boolean): void;
48
49
  (e: "toggle-select-mode", value: boolean): void;
50
+ (e: "toggle-theme", value: OpenCodeWidgetTheme): void;
49
51
  (e: "create-session"): void;
50
52
  (e: "select-session", session: OpenCodeWidgetSession): void;
51
53
  (e: "delete-session", session: OpenCodeWidgetSession): void;
@@ -15,18 +15,68 @@ function useOpenCodeWidgetContext() {
15
15
  }
16
16
  //#endregion
17
17
  //#region es/open-code-widget/src/components/Frame.vue.js
18
+ var __defProp$1 = Object.defineProperty;
19
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
20
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
21
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
22
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true,
26
+ value
27
+ }) : obj[key] = value;
28
+ var __spreadValues$1 = (a, b) => {
29
+ for (var prop in b || (b = {})) if (__hasOwnProp$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
30
+ if (__getOwnPropSymbols$1) {
31
+ for (var prop of __getOwnPropSymbols$1(b)) if (__propIsEnum$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]);
32
+ }
33
+ return a;
34
+ };
18
35
  var __vue_sfc__$7 = /* @__PURE__ */ (0, vue.defineComponent)({
19
36
  __name: "Frame",
20
37
  setup(__props, { expose: __expose }) {
21
38
  __expose();
22
- const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction } = useOpenCodeWidgetContext();
39
+ const iframeRef = (0, vue.ref)(null);
40
+ const { loading, showEmptyState, iframeSource: iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, theme, resolvedTheme } = useOpenCodeWidgetContext();
41
+ const iframeReady = (0, vue.ref)(false);
42
+ function sendMessageToIframe(type, data) {
43
+ var _a;
44
+ if (!((_a = iframeRef.value) == null ? void 0 : _a.contentWindow)) return;
45
+ iframeRef.value.contentWindow.postMessage(__spreadValues$1({ type }, data), "*");
46
+ }
47
+ function syncIframeTheme() {
48
+ sendMessageToIframe("OPENCODE_SET_THEME", { theme: resolvedTheme.value });
49
+ }
50
+ function handleIframeMessage(event) {
51
+ var _a;
52
+ if (((_a = event.data) == null ? void 0 : _a.type) === "OPENCODE_READY") syncIframeTheme();
53
+ }
54
+ (0, vue.watch)([theme, resolvedTheme], () => {
55
+ syncIframeTheme();
56
+ });
57
+ (0, vue.onMounted)(() => {
58
+ if (iframeRef.value) iframeRef.value.addEventListener("load", () => {
59
+ iframeReady.value = true;
60
+ });
61
+ window.addEventListener("message", handleIframeMessage);
62
+ });
63
+ (0, vue.onUnmounted)(() => {
64
+ window.removeEventListener("message", handleIframeMessage);
65
+ });
23
66
  const __returned__ = {
67
+ iframeRef,
24
68
  loading,
25
69
  showEmptyState,
26
70
  iframeSrc,
27
71
  emptyStateText,
28
72
  emptyStateActionText,
29
- handleEmptyAction
73
+ handleEmptyAction,
74
+ theme,
75
+ resolvedTheme,
76
+ iframeReady,
77
+ sendMessageToIframe,
78
+ syncIframeTheme,
79
+ handleIframeMessage
30
80
  };
31
81
  Object.defineProperty(__returned__, "__isScriptSetup", {
32
82
  enumerable: false,
@@ -63,6 +113,7 @@ function __vue_render__$7(_ctx, _cache, $props, $setup, $data, $options) {
63
113
  ])], 2),
64
114
  (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["opencode-loading-overlay", { visible: $setup.loading }]) }, [(0, vue.renderSlot)(_ctx.$slots, "loading", {}, () => [_cache[2] || (_cache[2] = (0, vue.createElementVNode)("div", { class: "opencode-loading-spinner" }, null, -1)), _cache[3] || (_cache[3] = (0, vue.createElementVNode)("div", { class: "opencode-loading-text" }, "加载中...", -1))])], 2),
65
115
  (0, vue.renderSlot)(_ctx.$slots, "content", {}, () => [(0, vue.createElementVNode)("iframe", {
116
+ ref: "iframeRef",
66
117
  class: "opencode-iframe",
67
118
  src: $setup.iframeSrc,
68
119
  allow: "clipboard-write; clipboard-read",
@@ -78,16 +129,33 @@ var __vue_sfc__$6 = /* @__PURE__ */ (0, vue.defineComponent)({
78
129
  __name: "Header",
79
130
  setup(__props, { expose: __expose }) {
80
131
  __expose();
81
- const { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, handleToggleSessionList, handleToggleSelectMode, handleClose } = useOpenCodeWidgetContext();
132
+ const { title, sessionListTitle, sessionListCollapsed, selectMode, selectEnabled, theme, resolvedTheme, handleToggleSessionList, handleToggleSelectMode, handleToggleTheme, handleClose } = useOpenCodeWidgetContext();
82
133
  const __returned__ = {
83
134
  title,
84
135
  sessionListTitle,
85
136
  sessionListCollapsed,
86
137
  selectMode,
87
138
  selectEnabled,
139
+ theme,
140
+ resolvedTheme,
88
141
  handleToggleSessionList,
89
142
  handleToggleSelectMode,
90
- handleClose
143
+ handleToggleTheme,
144
+ handleClose,
145
+ themeIconTitle: (0, vue.computed)(() => {
146
+ return `\u4E3B\u9898: ${{
147
+ auto: "自动",
148
+ light: "亮色",
149
+ dark: "暗色"
150
+ }[theme.value]} (${resolvedTheme.value})`;
151
+ }),
152
+ themeIconLabel: (0, vue.computed)(() => {
153
+ return `\u5207\u6362\u4E3B\u9898 - \u5F53\u524D: ${{
154
+ auto: "自动跟随系统",
155
+ light: "亮色主题",
156
+ dark: "暗色主题"
157
+ }[theme.value]}`;
158
+ })
91
159
  };
92
160
  Object.defineProperty(__returned__, "__isScriptSetup", {
93
161
  enumerable: false,
@@ -104,56 +172,97 @@ var _hoisted_3$4 = [
104
172
  "aria-expanded"
105
173
  ];
106
174
  var _hoisted_4$4 = ["aria-pressed", "disabled"];
107
- var _hoisted_5$4 = { class: "opencode-chat-header-title" };
108
- var _hoisted_6$3 = { class: "opencode-chat-header-actions" };
175
+ var _hoisted_5$4 = ["title", "aria-label"];
176
+ var _hoisted_6$3 = {
177
+ key: 0,
178
+ viewBox: "0 0 24 24",
179
+ width: "16",
180
+ height: "16",
181
+ fill: "none",
182
+ stroke: "currentColor",
183
+ "stroke-width": "2",
184
+ "aria-hidden": "true"
185
+ };
186
+ var _hoisted_7$2 = {
187
+ key: 1,
188
+ viewBox: "0 0 24 24",
189
+ width: "16",
190
+ height: "16",
191
+ fill: "none",
192
+ stroke: "currentColor",
193
+ "stroke-width": "2",
194
+ "aria-hidden": "true"
195
+ };
196
+ var _hoisted_8$2 = {
197
+ key: 2,
198
+ viewBox: "0 0 24 24",
199
+ width: "16",
200
+ height: "16",
201
+ fill: "none",
202
+ stroke: "currentColor",
203
+ "stroke-width": "2",
204
+ "aria-hidden": "true"
205
+ };
206
+ var _hoisted_9$1 = { class: "opencode-chat-header-title" };
207
+ var _hoisted_10 = { class: "opencode-chat-header-actions" };
109
208
  function __vue_render__$6(_ctx, _cache, $props, $setup, $data, $options) {
110
209
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$6, [
111
- (0, vue.createElementVNode)("div", _hoisted_2$4, [(0, vue.createElementVNode)("button", {
112
- class: "opencode-header-btn session-toggle",
113
- type: "button",
114
- title: $setup.sessionListTitle,
115
- "aria-label": $setup.sessionListTitle,
116
- "aria-expanded": !$setup.sessionListCollapsed,
117
- onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
118
- }, [(0, vue.renderSlot)(_ctx.$slots, "session-toggle-icon", {}, () => [_cache[3] || (_cache[3] = (0, vue.createElementVNode)("svg", {
119
- viewBox: "0 0 24 24",
120
- width: "16",
121
- height: "16",
122
- fill: "none",
123
- stroke: "currentColor",
124
- "stroke-width": "2",
125
- "aria-hidden": "true"
126
- }, [(0, vue.createElementVNode)("path", {
127
- d: "M4 6h16M4 12h16M4 18h16",
128
- "stroke-linecap": "round"
129
- })], -1))])], 8, _hoisted_3$4), (0, vue.createElementVNode)("button", {
130
- class: (0, vue.normalizeClass)(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
131
- type: "button",
132
- title: "选择页面元素 (Ctrl+P)",
133
- "aria-label": "选择页面元素",
134
- "aria-pressed": $setup.selectMode,
135
- disabled: !$setup.selectEnabled,
136
- onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
137
- }, [(0, vue.renderSlot)(_ctx.$slots, "select-icon", {}, () => [_cache[4] || (_cache[4] = (0, vue.createElementVNode)("svg", {
138
- viewBox: "0 0 1024 1024",
139
- width: "16",
140
- height: "16",
141
- "aria-hidden": "true"
142
- }, [(0, vue.createElementVNode)("path", {
143
- fill: "currentColor",
144
- 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"
145
- }), (0, vue.createElementVNode)("path", {
146
- fill: "currentColor",
147
- 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"
148
- })], -1))])], 10, _hoisted_4$4)]),
149
- (0, vue.createElementVNode)("span", _hoisted_5$4, (0, vue.toDisplayString)($setup.title), 1),
150
- (0, vue.createElementVNode)("div", _hoisted_6$3, [(0, vue.createElementVNode)("button", {
210
+ (0, vue.createElementVNode)("div", _hoisted_2$4, [
211
+ (0, vue.createElementVNode)("button", {
212
+ class: (0, vue.normalizeClass)(["opencode-header-btn session-toggle", { active: !$setup.sessionListCollapsed }]),
213
+ type: "button",
214
+ title: $setup.sessionListTitle,
215
+ "aria-label": $setup.sessionListTitle,
216
+ "aria-expanded": !$setup.sessionListCollapsed,
217
+ onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleToggleSessionList && $setup.handleToggleSessionList(...args))
218
+ }, [(0, vue.renderSlot)(_ctx.$slots, "session-toggle-icon", {}, () => [_cache[4] || (_cache[4] = (0, vue.createElementVNode)("svg", {
219
+ viewBox: "0 0 24 24",
220
+ width: "16",
221
+ height: "16",
222
+ fill: "none",
223
+ stroke: "currentColor",
224
+ "stroke-width": "2",
225
+ "aria-hidden": "true"
226
+ }, [(0, vue.createElementVNode)("path", {
227
+ d: "M4 6h16M4 12h16M4 18h16",
228
+ "stroke-linecap": "round"
229
+ })], -1))])], 10, _hoisted_3$4),
230
+ (0, vue.createElementVNode)("button", {
231
+ class: (0, vue.normalizeClass)(["opencode-header-btn select-btn", { active: $setup.selectMode }]),
232
+ type: "button",
233
+ title: "选择页面元素 (Ctrl+P)",
234
+ "aria-label": "选择页面元素",
235
+ "aria-pressed": $setup.selectMode,
236
+ disabled: !$setup.selectEnabled,
237
+ onClick: _cache[1] || (_cache[1] = (...args) => $setup.handleToggleSelectMode && $setup.handleToggleSelectMode(...args))
238
+ }, [(0, vue.renderSlot)(_ctx.$slots, "select-icon", {}, () => [_cache[5] || (_cache[5] = (0, vue.createElementVNode)("svg", {
239
+ viewBox: "0 0 1024 1024",
240
+ width: "16",
241
+ height: "16",
242
+ "aria-hidden": "true"
243
+ }, [(0, vue.createElementVNode)("path", {
244
+ fill: "currentColor",
245
+ 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"
246
+ }), (0, vue.createElementVNode)("path", {
247
+ fill: "currentColor",
248
+ 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"
249
+ })], -1))])], 10, _hoisted_4$4),
250
+ (0, vue.createElementVNode)("button", {
251
+ class: "opencode-header-btn theme-btn",
252
+ type: "button",
253
+ title: $setup.themeIconTitle,
254
+ "aria-label": $setup.themeIconLabel,
255
+ onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleToggleTheme && $setup.handleToggleTheme(...args))
256
+ }, [(0, vue.renderSlot)(_ctx.$slots, "theme-icon", {}, () => [$setup.theme === "light" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_6$3, [..._cache[6] || (_cache[6] = [(0, vue.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" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_7$2, [..._cache[7] || (_cache[7] = [(0, vue.createElementVNode)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }, null, -1)])])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("svg", _hoisted_8$2, [..._cache[8] || (_cache[8] = [(0, vue.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)
257
+ ]),
258
+ (0, vue.createElementVNode)("span", _hoisted_9$1, (0, vue.toDisplayString)($setup.title), 1),
259
+ (0, vue.createElementVNode)("div", _hoisted_10, [(0, vue.createElementVNode)("button", {
151
260
  class: "opencode-header-btn close",
152
261
  type: "button",
153
262
  title: "关闭",
154
263
  "aria-label": "关闭面板",
155
- onClick: _cache[2] || (_cache[2] = (...args) => $setup.handleClose && $setup.handleClose(...args))
156
- }, [(0, vue.renderSlot)(_ctx.$slots, "close-icon", {}, () => [_cache[5] || (_cache[5] = (0, vue.createElementVNode)("svg", {
264
+ onClick: _cache[3] || (_cache[3] = (...args) => $setup.handleClose && $setup.handleClose(...args))
265
+ }, [(0, vue.renderSlot)(_ctx.$slots, "close-icon", {}, () => [_cache[9] || (_cache[9] = (0, vue.createElementVNode)("svg", {
157
266
  viewBox: "0 0 24 24",
158
267
  width: "14",
159
268
  height: "14",
@@ -654,11 +763,39 @@ function useSession(options) {
654
763
  }
655
764
  //#endregion
656
765
  //#region es/open-code-widget/composables/use-widget.js
766
+ var THEME_CYCLE = [
767
+ "auto",
768
+ "light",
769
+ "dark"
770
+ ];
657
771
  function useWidget(options) {
772
+ const systemTheme = (0, vue.ref)("light");
773
+ function getSystemTheme() {
774
+ if (typeof window === "undefined") return "light";
775
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
776
+ }
777
+ let mediaQuery = null;
778
+ let handleChange = null;
779
+ (0, vue.onMounted)(() => {
780
+ if (typeof window === "undefined") return;
781
+ systemTheme.value = getSystemTheme();
782
+ mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
783
+ handleChange = (e) => {
784
+ systemTheme.value = e.matches ? "dark" : "light";
785
+ };
786
+ mediaQuery.addEventListener("change", handleChange);
787
+ });
788
+ (0, vue.onUnmounted)(() => {
789
+ if (mediaQuery && handleChange) mediaQuery.removeEventListener("change", handleChange);
790
+ });
791
+ const resolvedTheme = (0, vue.computed)(() => {
792
+ if (options.theme.value === "auto") return systemTheme.value;
793
+ return options.theme.value;
794
+ });
658
795
  const containerClasses = (0, vue.computed)(() => [
659
796
  "opencode-widget",
660
797
  options.position.value,
661
- `opencode-theme-${options.theme.value}`
798
+ `opencode-theme-${resolvedTheme.value}`
662
799
  ]);
663
800
  const buttonActive = (0, vue.computed)(() => !!(options.open.value || options.selectMode.value));
664
801
  const iframeSource = (0, vue.computed)(() => options.iframeSrc.value || "about:blank");
@@ -681,15 +818,22 @@ function useWidget(options) {
681
818
  function handleEmptyAction() {
682
819
  options.onEmptyAction();
683
820
  }
821
+ function handleToggleTheme() {
822
+ var _a;
823
+ const nextTheme = THEME_CYCLE[(THEME_CYCLE.indexOf(options.theme.value) + 1) % THEME_CYCLE.length];
824
+ (_a = options.onToggleTheme) == null || _a.call(options, nextTheme);
825
+ }
684
826
  return {
685
827
  buttonActive,
686
828
  containerClasses,
687
829
  iframeSource,
688
830
  sessionListTitle,
831
+ resolvedTheme,
689
832
  handleClose,
690
833
  handleEmptyAction,
691
834
  handleToggle,
692
- handleToggleSessionList
835
+ handleToggleSessionList,
836
+ handleToggleTheme
693
837
  };
694
838
  }
695
839
  //#endregion
@@ -723,6 +867,32 @@ function getElementDescription(element) {
723
867
  if (href && href !== "#") parts.push(`[href]`);
724
868
  return parts.join("");
725
869
  }
870
+ function getPreciseElementAtPoint(x, y, boundary) {
871
+ var _a, _b;
872
+ const highlight = document.querySelector(".opencode-element-highlight");
873
+ const tooltip = document.querySelector(".opencode-element-tooltip");
874
+ const highlightDisplay = ((_a = highlight == null ? void 0 : highlight.getAttribute("style")) == null ? void 0 : _a.includes("display: block")) ? "block" : "none";
875
+ const tooltipDisplay = ((_b = tooltip == null ? void 0 : tooltip.getAttribute("style")) == null ? void 0 : _b.includes("display: block")) ? "block" : "none";
876
+ if (highlight) highlight.style.display = "none";
877
+ if (tooltip) tooltip.style.display = "none";
878
+ let element = null;
879
+ try {
880
+ const elements = document.elementsFromPoint(x, y);
881
+ for (const el of elements) {
882
+ if (el.closest("#vue-inspector-container")) continue;
883
+ if (el.closest(".opencode-widget")) continue;
884
+ if (el.hasAttribute("data-v-inspector-ignore")) continue;
885
+ if (boundary.contains(el) || el === boundary) {
886
+ element = el;
887
+ break;
888
+ }
889
+ }
890
+ } finally {
891
+ if (highlight) highlight.style.display = highlightDisplay;
892
+ if (tooltip) tooltip.style.display = tooltipDisplay;
893
+ }
894
+ return element;
895
+ }
726
896
  function useInspector(options) {
727
897
  const highlightVisible = (0, vue.ref)(false);
728
898
  const highlightStyle = (0, vue.ref)({
@@ -748,7 +918,8 @@ function useInspector(options) {
748
918
  if (!inspector) return;
749
919
  const { targetNode, params } = inspector.getTargetNode(e);
750
920
  if (targetNode && params) {
751
- const rect = targetNode.getBoundingClientRect();
921
+ const elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
922
+ const rect = elementToHighlight.getBoundingClientRect();
752
923
  const widget = document.querySelector(".opencode-widget");
753
924
  let primary = "#3b82f6";
754
925
  let primaryBg = "rgba(59, 130, 246, 0.1)";
@@ -766,7 +937,7 @@ function useInspector(options) {
766
937
  border: `2px solid ${primary}`,
767
938
  background: primaryBg
768
939
  };
769
- const description = getElementDescription(targetNode);
940
+ const description = getElementDescription(elementToHighlight);
770
941
  const fileName = params.file ? params.file.split("/").pop() : "";
771
942
  let lineInfo = "";
772
943
  if (params.line) {
@@ -802,8 +973,9 @@ function useInspector(options) {
802
973
  if (options.selectMode.value) {
803
974
  const { targetNode, params } = inspector.getTargetNode(e);
804
975
  if (targetNode && params) {
805
- const innerText = getDirectText(targetNode);
806
- const description = getElementDescription(targetNode);
976
+ const elementToSelect = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode) || targetNode;
977
+ const innerText = getDirectText(elementToSelect);
978
+ const description = getElementDescription(elementToSelect);
807
979
  const elementInfo = {
808
980
  filePath: (_a = params.file) != null ? _a : null,
809
981
  line: (_b = params.line) != null ? _b : null,
@@ -903,7 +1075,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
903
1075
  theme: {
904
1076
  type: String,
905
1077
  required: false,
906
- default: "light"
1078
+ default: "auto"
907
1079
  },
908
1080
  title: {
909
1081
  type: String,
@@ -996,10 +1168,12 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
996
1168
  "update:sessionListCollapsed",
997
1169
  "update:currentSessionId",
998
1170
  "update:selectedElements",
1171
+ "update:theme",
999
1172
  "toggle",
1000
1173
  "close",
1001
1174
  "toggle-session-list",
1002
1175
  "toggle-select-mode",
1176
+ "toggle-theme",
1003
1177
  "create-session",
1004
1178
  "select-session",
1005
1179
  "delete-session",
@@ -1049,7 +1223,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1049
1223
  (0, vue.watch)(() => props.sessionListCollapsed, (val) => {
1050
1224
  localSessionListCollapsed.value = val;
1051
1225
  });
1052
- const { buttonActive, containerClasses, iframeSource, sessionListTitle, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList } = useWidget({
1226
+ const { buttonActive, containerClasses, iframeSource, sessionListTitle, resolvedTheme, handleClose, handleEmptyAction, handleToggle, handleToggleSessionList, handleToggleTheme } = useWidget({
1053
1227
  position: (0, vue.toRef)(props, "position"),
1054
1228
  theme: (0, vue.toRef)(props, "theme"),
1055
1229
  open: (0, vue.toRef)(props, "open"),
@@ -1075,6 +1249,10 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1075
1249
  },
1076
1250
  onEmptyAction: () => {
1077
1251
  emit("empty-action");
1252
+ },
1253
+ onToggleTheme: (newTheme) => {
1254
+ emit("update:theme", newTheme);
1255
+ emit("toggle-theme", newTheme);
1078
1256
  }
1079
1257
  });
1080
1258
  const { sessionItems, handleCreateSession, handleDeleteSession, handleSelectSession } = useSession({
@@ -1119,6 +1297,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1119
1297
  });
1120
1298
  provideOpenCodeWidgetContext({
1121
1299
  theme: (0, vue.toRef)(props, "theme"),
1300
+ resolvedTheme,
1122
1301
  title: (0, vue.toRef)(props, "title"),
1123
1302
  hotkeyLabel: (0, vue.toRef)(props, "hotkeyLabel"),
1124
1303
  selectShortcutLabel: (0, vue.toRef)(props, "selectShortcutLabel"),
@@ -1143,6 +1322,7 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1143
1322
  handleToggle,
1144
1323
  handleClose,
1145
1324
  handleToggleSessionList,
1325
+ handleToggleTheme,
1146
1326
  handleEmptyAction,
1147
1327
  handleCreateSession,
1148
1328
  handleSelectSession,
@@ -1181,10 +1361,12 @@ var __vue_sfc__ = /* @__PURE__ */ (0, vue.defineComponent)(__spreadProps(__sprea
1181
1361
  containerClasses,
1182
1362
  iframeSource,
1183
1363
  sessionListTitle,
1364
+ resolvedTheme,
1184
1365
  handleClose,
1185
1366
  handleEmptyAction,
1186
1367
  handleToggle,
1187
1368
  handleToggleSessionList,
1369
+ handleToggleTheme,
1188
1370
  sessionItems,
1189
1371
  handleCreateSession,
1190
1372
  handleDeleteSession,
@@ -1315,7 +1497,7 @@ __vue_sfc__.render = __vue_render__;
1315
1497
  var open_code_widget_default = __vue_sfc__;
1316
1498
  //#endregion
1317
1499
  //#region es/index.js
1318
- var version = "1.0.11";
1500
+ var version = "1.0.13";
1319
1501
  function install(app, options) {
1320
1502
  [open_code_widget_default].forEach((item) => {
1321
1503
  if (item.install) app.use(item, options);