@inspecto-dev/core 0.3.4 → 0.3.6

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/dist/index.cjs CHANGED
@@ -1059,7 +1059,9 @@ var init_styles_overlay_menu = __esm({
1059
1059
  border: 1px solid var(--inspecto-border-subtle);
1060
1060
  border-radius: var(--inspecto-radius-lg);
1061
1061
  padding: 10px;
1062
- min-width: 304px;
1062
+ width: 304px;
1063
+ max-width: calc(100vw - 16px);
1064
+ box-sizing: border-box;
1063
1065
  box-shadow: var(--inspecto-shadow-floating);
1064
1066
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
1065
1067
  color: var(--inspecto-text-primary);
@@ -3117,7 +3119,7 @@ function createBadge(ctx) {
3117
3119
  const state = asLauncherContext(ctx);
3118
3120
  const btn = document.createElement("div");
3119
3121
  btn.className = badgeClass;
3120
- btn.style.display = "flex";
3122
+ btn.style.visibility = "hidden";
3121
3123
  const indicator = document.createElement("span");
3122
3124
  indicator.className = `${badgeClass}-indicator`;
3123
3125
  indicator.dataset.inspectoLauncherIndicator = "true";
@@ -3202,14 +3204,85 @@ function createBadge(ctx) {
3202
3204
  titleBlock.append(titleSpan, stateSpan);
3203
3205
  content.append(indicator, titleBlock);
3204
3206
  btn.append(content, eyes, panel);
3207
+ let isDragging = false;
3208
+ let dragStartX = 0;
3209
+ let dragStartY = 0;
3210
+ let initialBadgeX = 0;
3211
+ let initialBadgeY = 0;
3212
+ const handleDragStart = (e) => {
3213
+ const target = e.target;
3214
+ if (target.closest(`.${badgeClass}-panel`) || target.closest(`[data-inspecto-launcher-action]`)) {
3215
+ return;
3216
+ }
3217
+ if (e.type === "mousedown" && e.button !== 0) return;
3218
+ const clientX = e.type === "touchstart" ? e.touches[0].clientX : e.clientX;
3219
+ const clientY = e.type === "touchstart" ? e.touches[0].clientY : e.clientY;
3220
+ dragStartX = clientX;
3221
+ dragStartY = clientY;
3222
+ const rect = btn.getBoundingClientRect();
3223
+ initialBadgeX = rect.left;
3224
+ initialBadgeY = rect.top;
3225
+ isDragging = false;
3226
+ document.addEventListener("mousemove", handleDragMove, { passive: false });
3227
+ document.addEventListener("mouseup", handleDragEnd);
3228
+ document.addEventListener("touchmove", handleDragMove, { passive: false });
3229
+ document.addEventListener("touchend", handleDragEnd);
3230
+ };
3231
+ const handleDragMove = (e) => {
3232
+ const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
3233
+ const clientY = e.type === "touchmove" ? e.touches[0].clientY : e.clientY;
3234
+ const dx = clientX - dragStartX;
3235
+ const dy = clientY - dragStartY;
3236
+ if (!isDragging && Math.hypot(dx, dy) > 5) {
3237
+ isDragging = true;
3238
+ btn.style.transition = "none";
3239
+ }
3240
+ if (isDragging) {
3241
+ e.preventDefault();
3242
+ const maxX = window.innerWidth - btn.offsetWidth;
3243
+ const maxY = window.innerHeight - btn.offsetHeight;
3244
+ let newX = initialBadgeX + dx;
3245
+ let newY = initialBadgeY + dy;
3246
+ newX = Math.max(0, Math.min(newX, maxX));
3247
+ newY = Math.max(0, Math.min(newY, maxY));
3248
+ btn.style.bottom = "auto";
3249
+ btn.style.right = "auto";
3250
+ btn.style.left = `${newX}px`;
3251
+ btn.style.top = `${newY}px`;
3252
+ }
3253
+ };
3254
+ const handleDragEnd = () => {
3255
+ document.removeEventListener("mousemove", handleDragMove);
3256
+ document.removeEventListener("mouseup", handleDragEnd);
3257
+ document.removeEventListener("touchmove", handleDragMove);
3258
+ document.removeEventListener("touchend", handleDragEnd);
3259
+ if (isDragging) {
3260
+ btn.style.transition = "";
3261
+ setTimeout(() => {
3262
+ isDragging = false;
3263
+ }, 0);
3264
+ }
3265
+ };
3266
+ btn.addEventListener("mousedown", handleDragStart);
3267
+ btn.addEventListener("touchstart", handleDragStart, { passive: false });
3205
3268
  btn.addEventListener("click", (event) => {
3206
3269
  var _a2, _b;
3270
+ if (isDragging) {
3271
+ event.preventDefault();
3272
+ event.stopPropagation();
3273
+ return;
3274
+ }
3207
3275
  if ((_b = (_a2 = event.target).closest) == null ? void 0 : _b.call(_a2, `[data-inspecto-launcher-action]`)) return;
3208
3276
  state.launcherPanelOpen = !state.launcherPanelOpen;
3209
3277
  state.updateBadgeContent();
3210
3278
  });
3211
3279
  state.shadowRootEl.appendChild(btn);
3212
3280
  updateLauncherEye(state);
3281
+ requestAnimationFrame(() => {
3282
+ requestAnimationFrame(() => {
3283
+ btn.style.visibility = "";
3284
+ });
3285
+ });
3213
3286
  return btn;
3214
3287
  }
3215
3288
  function setPaused(ctx, value) {
@@ -3797,7 +3870,11 @@ function buildCustomInspectPrompt(input) {
3797
3870
  const prompt = appendCssContextToPrompt(
3798
3871
  appendScreenshotContextToPrompt(
3799
3872
  appendRuntimeContextToPrompt(
3800
- buildPrompt(CUSTOM_PROMPT_TEMPLATE(input.ask.trim()), input.location, snippetResult),
3873
+ buildPrompt(
3874
+ buildCustomInspectPromptTemplate(input.ask.trim(), input.location, input.targetLabel),
3875
+ input.location,
3876
+ snippetResult
3877
+ ),
3801
3878
  (_b = (_a2 = input.runtimeContext) == null ? void 0 : _a2.records) != null ? _b : []
3802
3879
  ),
3803
3880
  (_c = input.screenshotContext) != null ? _c : null
@@ -3810,6 +3887,19 @@ function buildCustomInspectPrompt(input) {
3810
3887
  };
3811
3888
  });
3812
3889
  }
3890
+ function buildCustomInspectPromptTemplate(ask, location, targetLabel) {
3891
+ const sections = [CUSTOM_PROMPT_TEMPLATE(ask)];
3892
+ if (targetLabel == null ? void 0 : targetLabel.trim()) {
3893
+ sections.push(`Selected component:
3894
+ - ${targetLabel.trim()}`);
3895
+ }
3896
+ sections.push(
3897
+ `Source location:
3898
+ - file: ${location.file}
3899
+ - location: ${location.line}:${location.column}`
3900
+ );
3901
+ return sections.join("\n\n");
3902
+ }
3813
3903
  var init_menu_send = __esm({
3814
3904
  "src/menu-send.ts"() {
3815
3905
  "use strict";
@@ -3829,7 +3919,14 @@ function createMenuHeaderDom(input) {
3829
3919
  headerCopy.style.display = "flex";
3830
3920
  headerCopy.style.flexDirection = "column";
3831
3921
  headerCopy.style.gap = "2px";
3922
+ headerCopy.style.minWidth = "0";
3923
+ headerCopy.style.flex = "1 1 auto";
3832
3924
  const title = document.createElement("strong");
3925
+ title.style.display = "block";
3926
+ title.style.minWidth = "0";
3927
+ title.style.whiteSpace = "nowrap";
3928
+ title.style.overflow = "hidden";
3929
+ title.style.textOverflow = "ellipsis";
3833
3930
  title.textContent = ((_a2 = input.targetLabel) == null ? void 0 : _a2.trim()) || input.location.file.split("/").pop() || input.location.file;
3834
3931
  const meta = document.createElement("div");
3835
3932
  meta.className = menuMetaClass;
@@ -3933,6 +4030,26 @@ var init_menu_header = __esm({
3933
4030
  }
3934
4031
  });
3935
4032
 
4033
+ // src/menu-position.ts
4034
+ function resolveMenuPosition(input) {
4035
+ var _a2;
4036
+ const edgeMargin = (_a2 = input.edgeMargin) != null ? _a2 : DEFAULT_EDGE_MARGIN;
4037
+ const safeWidth = input.viewport.width > 0 ? input.viewport.width : input.menuRect.width + edgeMargin * 2;
4038
+ const safeHeight = input.viewport.height > 0 ? input.viewport.height : input.menuRect.height + edgeMargin * 2;
4039
+ const maxLeft = Math.max(safeWidth - input.menuRect.width - edgeMargin, edgeMargin);
4040
+ const left = Math.max(edgeMargin, Math.min(input.clickX, maxLeft));
4041
+ const maxTop = Math.max(safeHeight - input.menuRect.height - edgeMargin, edgeMargin);
4042
+ const top = Math.max(edgeMargin, Math.min(input.clickY + edgeMargin, maxTop));
4043
+ return { left, top };
4044
+ }
4045
+ var DEFAULT_EDGE_MARGIN;
4046
+ var init_menu_position = __esm({
4047
+ "src/menu-position.ts"() {
4048
+ "use strict";
4049
+ DEFAULT_EDGE_MARGIN = 8;
4050
+ }
4051
+ });
4052
+
3936
4053
  // src/menu.ts
3937
4054
  function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose, deps = {}) {
3938
4055
  var _a2, _b, _c;
@@ -3947,6 +4064,10 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose,
3947
4064
  const canAttachCssContext2 = typeof deps.captureCssContextPrompt === "function";
3948
4065
  const menu = document.createElement("div");
3949
4066
  menu.className = menuClass;
4067
+ menu.style.width = "304px";
4068
+ menu.style.maxWidth = "calc(100vw - 16px)";
4069
+ menu.style.boxSizing = "border-box";
4070
+ menu.style.pointerEvents = "auto";
3950
4071
  const {
3951
4072
  header,
3952
4073
  headerActions,
@@ -4033,25 +4154,36 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose,
4033
4154
  menu.appendChild(askAiSection);
4034
4155
  const actionsSection = createMenuSection();
4035
4156
  menu.appendChild(actionsSection);
4036
- const viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0);
4037
- const safeWidth = viewportWidth > 0 ? viewportWidth : MENU_WIDTH;
4038
- menu.style.left = `${Math.min(clickX, Math.max(safeWidth - MENU_WIDTH, 0))}px`;
4157
+ menu.style.left = `${clickX}px`;
4039
4158
  menu.style.visibility = "hidden";
4040
4159
  menu.style.display = "block";
4041
4160
  shadowRoot.appendChild(menu);
4042
4161
  const updatePosition = () => {
4043
4162
  const rect = menu.getBoundingClientRect();
4044
- const viewportHeight = Math.max(
4045
- document.documentElement.clientHeight || 0,
4046
- window.innerHeight || 0
4047
- );
4048
- const safeHeight = viewportHeight > 0 ? viewportHeight : rect.height + 16;
4049
- menu.style.top = `${Math.min(clickY + 8, Math.max(safeHeight - rect.height - 8, 0))}px`;
4163
+ const { left: nextLeft, top: nextTop } = resolveMenuPosition({
4164
+ clickX,
4165
+ clickY,
4166
+ menuRect: { width: rect.width, height: rect.height },
4167
+ viewport: {
4168
+ width: document.documentElement.clientWidth || window.innerWidth || 0,
4169
+ height: document.documentElement.clientHeight || window.innerHeight || 0
4170
+ }
4171
+ });
4172
+ menu.style.left = `${nextLeft}px`;
4173
+ menu.style.top = `${nextTop}px`;
4050
4174
  };
4051
4175
  updatePosition();
4052
4176
  menu.style.visibility = "visible";
4053
4177
  setTimeout(() => input.focus(), 0);
4054
4178
  const onDocClick = (e) => {
4179
+ const eventTarget = e.target;
4180
+ if (eventTarget) {
4181
+ if (eventTarget.closest(
4182
+ '[role="dialog"], [role="menu"], [role="tooltip"], [role="presentation"], [role="listbox"], [data-radix-popper-content-wrapper], [data-radix-focus-guard]'
4183
+ )) {
4184
+ return;
4185
+ }
4186
+ }
4055
4187
  const path = e.composedPath();
4056
4188
  if (path.includes(menu)) return;
4057
4189
  cleanup();
@@ -4167,15 +4299,16 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose,
4167
4299
  const requestRuntimeContext = resolveRuntimeContext();
4168
4300
  const requestScreenshotContext = yield resolveScreenshotContext();
4169
4301
  const requestCssContextPrompt = resolveCssContextPrompt();
4170
- const built = yield buildCustomInspectPrompt({
4302
+ const built = yield buildCustomInspectPrompt(__spreadProps(__spreadValues({
4171
4303
  location,
4172
- ask: input.value.trim(),
4304
+ ask: input.value.trim()
4305
+ }, deps.targetLabel ? { targetLabel: deps.targetLabel } : {}), {
4173
4306
  includeSnippet,
4174
4307
  maxSnippetLines,
4175
4308
  runtimeContext: requestRuntimeContext,
4176
4309
  screenshotContext: requestScreenshotContext,
4177
4310
  cssContextPrompt: requestCssContextPrompt
4178
- });
4311
+ }));
4179
4312
  yield openAndSendInspectPrompt({
4180
4313
  location,
4181
4314
  promptText: built.prompt,
@@ -4268,7 +4401,6 @@ function showIntentMenu(shadowRoot, location, clickX, clickY, options, onClose,
4268
4401
  });
4269
4402
  return cleanup;
4270
4403
  }
4271
- var MENU_WIDTH;
4272
4404
  var init_menu = __esm({
4273
4405
  "src/menu.ts"() {
4274
4406
  "use strict";
@@ -4276,9 +4408,9 @@ var init_menu = __esm({
4276
4408
  init_menu_send();
4277
4409
  init_http();
4278
4410
  init_menu_header();
4411
+ init_menu_position();
4279
4412
  init_menu_helpers();
4280
4413
  init_styles();
4281
- MENU_WIDTH = 280;
4282
4414
  }
4283
4415
  });
4284
4416
 
@@ -4913,6 +5045,18 @@ function handleMouseMove(ctx, event) {
4913
5045
  state.lastPointerX = event.clientX;
4914
5046
  state.lastPointerY = event.clientY;
4915
5047
  state.updateLauncherEye();
5048
+ if (state.cleanupMenu !== null) {
5049
+ const eventTarget = event.target;
5050
+ if (eventTarget) {
5051
+ if (eventTarget.closest(
5052
+ '[role="dialog"], [role="menu"], [role="tooltip"], [role="presentation"], [role="listbox"], [data-radix-popper-content-wrapper], [data-radix-focus-guard]'
5053
+ )) {
5054
+ return;
5055
+ }
5056
+ }
5057
+ state.overlay.hide();
5058
+ return;
5059
+ }
4916
5060
  const isActive = state.isInspectorActive(event);
4917
5061
  if (!isActive) {
4918
5062
  state.overlay.hide();
@@ -4934,8 +5078,18 @@ function handleMouseMove(ctx, event) {
4934
5078
  event.stopPropagation();
4935
5079
  }
4936
5080
  function handleTrigger(ctx, event) {
4937
- var _a2;
4938
5081
  const state = asInteractionContext(ctx);
5082
+ if (state.cleanupMenu !== null) {
5083
+ const eventTarget = event.target;
5084
+ if (eventTarget) {
5085
+ if (eventTarget.closest(
5086
+ '[role="dialog"], [role="menu"], [role="tooltip"], [role="presentation"], [role="listbox"], [data-radix-popper-content-wrapper], [data-radix-focus-guard]'
5087
+ )) {
5088
+ return;
5089
+ }
5090
+ }
5091
+ return;
5092
+ }
4939
5093
  if (!state.isInspectorActive(event)) return;
4940
5094
  const target = findInspectable(event.target);
4941
5095
  if (!target) return;
@@ -4954,11 +5108,12 @@ function handleTrigger(ctx, event) {
4954
5108
  return;
4955
5109
  }
4956
5110
  if (state.shouldQuickJumpOnTrigger(event)) {
4957
- (_a2 = state.cleanupMenu) == null ? void 0 : _a2.call(state);
5111
+ state.overlay.hide();
4958
5112
  state.cleanupMenu = null;
4959
5113
  void openFile(loc);
4960
5114
  return;
4961
5115
  }
5116
+ state.overlay.hide();
4962
5117
  state.openInspectMenu(loc, event.clientX, event.clientY, target);
4963
5118
  }
4964
5119
  function handleKeyDown(ctx, event) {
@@ -4986,6 +5141,7 @@ function openInspectMenu(ctx, loc, clientX, clientY, targetElement) {
4986
5141
  var _a2, _b;
4987
5142
  const state = asInteractionContext(ctx);
4988
5143
  (_a2 = state.cleanupMenu) == null ? void 0 : _a2.call(state);
5144
+ state.style.pointerEvents = "auto";
4989
5145
  state.cleanupMenu = showIntentMenu(
4990
5146
  state.shadowRootEl,
4991
5147
  loc,
@@ -4993,6 +5149,7 @@ function openInspectMenu(ctx, loc, clientX, clientY, targetElement) {
4993
5149
  clientY,
4994
5150
  state.options,
4995
5151
  () => {
5152
+ state.style.pointerEvents = "none";
4996
5153
  state.cleanupMenu = null;
4997
5154
  },
4998
5155
  {
@@ -5516,11 +5673,14 @@ function createAnnotateSidebarRenderers({
5516
5673
  titleEl.style.letterSpacing = "0.04em";
5517
5674
  titleEl.textContent = title;
5518
5675
  const contentEl = document.createElement("div");
5676
+ contentEl.style.minWidth = "0";
5677
+ contentEl.style.whiteSpace = "normal";
5678
+ contentEl.style.overflowWrap = "anywhere";
5679
+ contentEl.style.wordBreak = "break-word";
5519
5680
  if (typeof content === "string") {
5520
5681
  contentEl.style.fontSize = "13px";
5521
5682
  contentEl.style.color = "rgba(255, 255, 255, 0.9)";
5522
5683
  contentEl.style.lineHeight = "1.4";
5523
- contentEl.style.wordBreak = "break-word";
5524
5684
  if (title === "NOTE" && !chip.note.trim()) {
5525
5685
  contentEl.style.fontStyle = "italic";
5526
5686
  contentEl.style.color = "rgba(255, 255, 255, 0.4)";
@@ -5533,9 +5693,13 @@ function createAnnotateSidebarRenderers({
5533
5693
  return section;
5534
5694
  };
5535
5695
  const elementValue = document.createElement("div");
5696
+ elementValue.style.minWidth = "0";
5536
5697
  elementValue.style.fontFamily = "monospace";
5537
5698
  elementValue.style.fontSize = "13px";
5538
5699
  elementValue.style.color = "#9cdcfe";
5700
+ elementValue.style.whiteSpace = "normal";
5701
+ elementValue.style.overflowWrap = "anywhere";
5702
+ elementValue.style.wordBreak = "break-word";
5539
5703
  elementValue.textContent = chip.label;
5540
5704
  activeTooltip.appendChild(createSection("ELEMENT", elementValue));
5541
5705
  activeTooltip.appendChild(createSection("NOTE", chip.note.trim() || "No note provided"));
@@ -5570,9 +5734,12 @@ function createAnnotateSidebarRenderers({
5570
5734
  chipElement.className = annotateSidebarChipClass;
5571
5735
  chipElement.contentEditable = "false";
5572
5736
  chipElement.style.margin = "0 4px";
5737
+ chipElement.style.boxSizing = "border-box";
5573
5738
  chipElement.style.display = "inline-flex";
5574
5739
  chipElement.style.alignItems = "center";
5575
5740
  chipElement.style.gap = "5px";
5741
+ chipElement.style.minWidth = "0";
5742
+ chipElement.style.maxWidth = "calc(100% - 8px)";
5576
5743
  chipElement.style.verticalAlign = "middle";
5577
5744
  chipElement.tabIndex = 0;
5578
5745
  chipElement.setAttribute("role", "button");
@@ -5580,6 +5747,11 @@ function createAnnotateSidebarRenderers({
5580
5747
  chipElement.dataset.state = chip.state;
5581
5748
  const label = document.createElement("span");
5582
5749
  label.dataset.annotateChipLabel = "true";
5750
+ label.style.flex = "1 1 auto";
5751
+ label.style.minWidth = "0";
5752
+ label.style.overflow = "hidden";
5753
+ label.style.textOverflow = "ellipsis";
5754
+ label.style.whiteSpace = "nowrap";
5583
5755
  label.textContent = chip.label;
5584
5756
  const actionSlot = document.createElement("span");
5585
5757
  actionSlot.style.position = "relative";
@@ -6041,6 +6213,7 @@ function createOverlay(shadowRoot) {
6041
6213
  overlay.style.display = "none";
6042
6214
  const tooltip = document.createElement("div");
6043
6215
  tooltip.className = tooltipClass;
6216
+ tooltip.style.display = "none";
6044
6217
  const tagSpan = document.createElement("span");
6045
6218
  tagSpan.className = tagClass;
6046
6219
  const idSpan = document.createElement("span");
@@ -6073,7 +6246,7 @@ function createOverlay(shadowRoot) {
6073
6246
  tagSpan.textContent = tagName;
6074
6247
  idSpan.textContent = el.id ? `#${el.id}` : "";
6075
6248
  const classes = Array.from(el.classList).map((c) => `.${c}`).join("");
6076
- classSpan.textContent = classes;
6249
+ classSpan.textContent = summarizeClasses(classes);
6077
6250
  dimSpan.textContent = `${Math.round(rect.width)} \xD7 ${Math.round(rect.height)}`;
6078
6251
  sourceSpan.textContent = sourceLabel;
6079
6252
  tooltip.style.visibility = "hidden";
@@ -6113,13 +6286,18 @@ function createOverlay(shadowRoot) {
6113
6286
  }
6114
6287
  return { show, hide };
6115
6288
  }
6116
- var GAP, EDGE_MARGIN;
6289
+ function summarizeClasses(classes) {
6290
+ if (classes.length <= MAX_CLASS_SUMMARY_LENGTH) return classes;
6291
+ return `${classes.slice(0, MAX_CLASS_SUMMARY_LENGTH - 3)}...`;
6292
+ }
6293
+ var GAP, EDGE_MARGIN, MAX_CLASS_SUMMARY_LENGTH;
6117
6294
  var init_overlay = __esm({
6118
6295
  "src/overlay.ts"() {
6119
6296
  "use strict";
6120
6297
  init_styles();
6121
6298
  GAP = 8;
6122
6299
  EDGE_MARGIN = 4;
6300
+ MAX_CLASS_SUMMARY_LENGTH = 96;
6123
6301
  }
6124
6302
  });
6125
6303
 
@@ -6147,6 +6325,11 @@ function resetAnnotateState(state) {
6147
6325
  }
6148
6326
  function connect(ctx, createAnnotateOverlay2) {
6149
6327
  const state = asLifecycleContext(ctx);
6328
+ const host = state;
6329
+ host.style.position = "fixed";
6330
+ host.style.inset = "0";
6331
+ host.style.pointerEvents = "none";
6332
+ host.style.zIndex = "2147483646";
6150
6333
  state.shadowRootEl = state.attachShadow({ mode: "open" });
6151
6334
  const style = document.createElement("style");
6152
6335
  style.textContent = inspectorStyles;
@@ -6693,7 +6876,7 @@ var init_component = __esm({
6693
6876
  });
6694
6877
  }
6695
6878
  };
6696
- if (typeof customElements !== "undefined") {
6879
+ if (typeof customElements !== "undefined" && !customElements.get("inspecto-overlay")) {
6697
6880
  customElements.define("inspecto-overlay", InspectoElement);
6698
6881
  }
6699
6882
  }