@lexingtonthemes/astro-image-inspector 0.2.2 → 0.2.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar-app.d.ts","sourceRoot":"","sources":["../src/toolbar-app.ts"],"names":[],"mappings":";AAkSA,wBAA2B"}
1
+ {"version":3,"file":"toolbar-app.d.ts","sourceRoot":"","sources":["../src/toolbar-app.ts"],"names":[],"mappings":";AAmVA,wBAA2B"}
@@ -122,7 +122,8 @@ function showOverlay(rect, hasWarnings) {
122
122
  ? "rgba(251, 191, 36, 0.9)"
123
123
  : "rgba(34, 197, 94, 0.8)";
124
124
  }
125
- function showPanel(info) {
125
+ function showPanel(info, options = {}) {
126
+ const { pinned = false, onClose } = options;
126
127
  const el = ensurePanel();
127
128
  el.style.display = "block";
128
129
  const srcShort = info.src.length > 52 ? info.src.slice(0, 49) + "…" : info.src;
@@ -131,8 +132,12 @@ function showPanel(info) {
131
132
  : "none";
132
133
  const altShort = info.alt.length > 40 ? info.alt.slice(0, 37) + "…" : info.alt;
133
134
  const sizesShort = info.sizes.length > 36 ? info.sizes.slice(0, 33) + "…" : info.sizes;
135
+ const closeButton = pinned
136
+ ? `<button type="button" data-action="close" style="padding: 4px 8px; font-size: 11px; cursor: pointer; border-radius: 4px; border: 1px solid #64748b; background: #334155; color: #e2e8f0;">Close</button>`
137
+ : "";
134
138
  el.innerHTML = `
135
139
  <div style="display: grid; gap: 6px;">
140
+ ${pinned ? `<div style="font-size: 11px; color: #94a3b8; margin-bottom: 2px;">Pinned — click another image or Close</div>` : ""}
136
141
  <div><strong>src</strong><br/><span style="word-break: break-all;">${srcShort}</span></div>
137
142
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px;">
138
143
  <div><strong>natural</strong><br/>${info.naturalWidth}×${info.naturalHeight}</div>
@@ -149,7 +154,8 @@ function showPanel(info) {
149
154
  ${info.sizes !== "(none)" ? `<div><strong>sizes</strong><br/>${sizesShort}</div>` : ""}
150
155
  <div><strong>width/height attrs</strong> ${info.attrWidth} × ${info.attrHeight}</div>
151
156
  <div><strong>warnings</strong> ${warnText}</div>
152
- <div style="display: flex; gap: 8px; margin-top: 6px;">
157
+ <div style="display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap;">
158
+ ${closeButton}
153
159
  <button type="button" data-action="copy" style="padding: 4px 8px; font-size: 11px; cursor: pointer; border-radius: 4px; border: 1px solid #64748b; background: #334155; color: #e2e8f0;">Copy src</button>
154
160
  <button type="button" data-action="open" style="padding: 4px 8px; font-size: 11px; cursor: pointer; border-radius: 4px; border: 1px solid #64748b; background: #334155; color: #e2e8f0;">Open in tab</button>
155
161
  </div>
@@ -158,21 +164,28 @@ function showPanel(info) {
158
164
  el.querySelectorAll("[data-action]").forEach((btn) => {
159
165
  btn.addEventListener("click", (e) => {
160
166
  e.preventDefault();
161
- if (btn.dataset.action === "copy") {
167
+ e.stopPropagation();
168
+ const action = btn.dataset.action;
169
+ if (action === "close" && onClose) {
170
+ onClose();
171
+ return;
172
+ }
173
+ if (action === "copy") {
162
174
  void navigator.clipboard.writeText(info.src);
163
175
  btn.textContent = "Copied!";
164
176
  setTimeout(() => (btn.textContent = "Copy src"), 1200);
165
177
  }
166
- else {
178
+ else if (action === "open") {
167
179
  window.open(info.src, "_blank", "noopener");
168
180
  }
169
181
  });
170
182
  });
171
183
  }
172
- const INSTRUCTION_TEXT = "Hover an image to inspect it.";
184
+ const INSTRUCTION_TEXT = "Hover an image to inspect it. Click to pin the info card.";
173
185
  function enableInspector(windowContent) {
174
186
  windowContent.textContent = INSTRUCTION_TEXT;
175
187
  windowContent.style.display = "";
188
+ let pinnedImage = null;
176
189
  const showInstruction = () => {
177
190
  windowContent.textContent = INSTRUCTION_TEXT;
178
191
  windowContent.style.display = "";
@@ -181,32 +194,64 @@ function enableInspector(windowContent) {
181
194
  windowContent.textContent = "";
182
195
  windowContent.style.display = "none";
183
196
  };
197
+ const unpin = () => {
198
+ pinnedImage = null;
199
+ hideOverlay();
200
+ hidePanel();
201
+ showInstruction();
202
+ };
184
203
  const onMouseOver = (event) => {
185
204
  const target = event.target;
186
205
  if (!(target instanceof HTMLImageElement)) {
187
- hideOverlay();
188
- hidePanel();
189
- showInstruction();
206
+ if (!pinnedImage) {
207
+ hideOverlay();
208
+ hidePanel();
209
+ showInstruction();
210
+ }
211
+ else {
212
+ hideOverlay();
213
+ }
190
214
  return;
191
215
  }
192
216
  hideInstruction();
193
217
  const info = getImageInfo(target);
194
218
  showOverlay(target.getBoundingClientRect(), info.warnings.length > 0);
195
- showPanel(info);
219
+ if (!pinnedImage) {
220
+ showPanel(info);
221
+ }
196
222
  };
197
223
  const onMouseOut = (event) => {
198
224
  const related = event.relatedTarget;
225
+ if (pinnedImage) {
226
+ if (related && document.body.contains(related))
227
+ return;
228
+ hideOverlay();
229
+ return;
230
+ }
199
231
  if (related && document.body.contains(related))
200
232
  return;
201
233
  hideOverlay();
202
234
  hidePanel();
203
235
  showInstruction();
204
236
  };
237
+ const onClick = (event) => {
238
+ const target = event.target;
239
+ if (!(target instanceof HTMLImageElement))
240
+ return;
241
+ event.preventDefault();
242
+ event.stopPropagation();
243
+ pinnedImage = target;
244
+ const info = getImageInfo(target);
245
+ showOverlay(target.getBoundingClientRect(), info.warnings.length > 0);
246
+ showPanel(info, { pinned: true, onClose: unpin });
247
+ };
205
248
  document.addEventListener("mouseover", onMouseOver, true);
206
249
  document.addEventListener("mouseout", onMouseOut, true);
250
+ document.addEventListener("click", onClick, true);
207
251
  return () => {
208
252
  document.removeEventListener("mouseover", onMouseOver, true);
209
253
  document.removeEventListener("mouseout", onMouseOut, true);
254
+ document.removeEventListener("click", onClick, true);
210
255
  hideOverlay();
211
256
  hidePanel();
212
257
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexingtonthemes/astro-image-inspector",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Astro Dev Toolbar app to inspect images on hover: actual size, render size, and warnings",
5
5
  "type": "module",
6
6
  "exports": {