@designtools/next-plugin 0.1.3 → 0.1.7

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,403 +0,0 @@
1
- "use client";
2
- import "./chunk-Y6FXYEAI.mjs";
3
-
4
- // src/codecanvas.tsx
5
- import { useEffect, useRef } from "react";
6
- function CodeCanvas() {
7
- const stateRef = useRef({
8
- selectionMode: false,
9
- hoveredElement: null,
10
- selectedElement: null,
11
- selectedDomPath: null,
12
- overlayRafId: null,
13
- inlineStyleBackups: /* @__PURE__ */ new Map(),
14
- highlightOverlay: null,
15
- tooltip: null,
16
- selectedOverlay: null
17
- });
18
- useEffect(() => {
19
- const s = stateRef.current;
20
- s.highlightOverlay = document.createElement("div");
21
- s.highlightOverlay.id = "tool-highlight";
22
- Object.assign(s.highlightOverlay.style, {
23
- position: "fixed",
24
- pointerEvents: "none",
25
- border: "2px solid #3b82f6",
26
- backgroundColor: "rgba(59, 130, 246, 0.08)",
27
- borderRadius: "2px",
28
- zIndex: "99999",
29
- display: "none",
30
- transition: "all 0.1s ease"
31
- });
32
- document.body.appendChild(s.highlightOverlay);
33
- s.tooltip = document.createElement("div");
34
- s.tooltip.id = "tool-tooltip";
35
- Object.assign(s.tooltip.style, {
36
- position: "fixed",
37
- pointerEvents: "none",
38
- backgroundColor: "#1e1e2e",
39
- color: "#cdd6f4",
40
- padding: "3px 8px",
41
- borderRadius: "4px",
42
- fontSize: "11px",
43
- fontFamily: "ui-monospace, monospace",
44
- zIndex: "100000",
45
- display: "none",
46
- whiteSpace: "nowrap",
47
- boxShadow: "0 2px 8px rgba(0,0,0,0.3)"
48
- });
49
- document.body.appendChild(s.tooltip);
50
- s.selectedOverlay = document.createElement("div");
51
- s.selectedOverlay.id = "tool-selected";
52
- Object.assign(s.selectedOverlay.style, {
53
- position: "fixed",
54
- pointerEvents: "none",
55
- border: "2px solid #f59e0b",
56
- backgroundColor: "rgba(245, 158, 11, 0.06)",
57
- borderRadius: "2px",
58
- zIndex: "99998",
59
- display: "none"
60
- });
61
- document.body.appendChild(s.selectedOverlay);
62
- function getElementName(el) {
63
- const slot = el.getAttribute("data-slot");
64
- if (slot) return slot.charAt(0).toUpperCase() + slot.slice(1);
65
- return `<${el.tagName.toLowerCase()}>`;
66
- }
67
- function getDomPath(el) {
68
- const parts = [];
69
- let current = el;
70
- while (current && current !== document.body) {
71
- const parent = current.parentElement;
72
- if (parent) {
73
- const idx = Array.from(parent.children).indexOf(current) + 1;
74
- parts.unshift(`${current.tagName.toLowerCase()}:nth-child(${idx})`);
75
- } else {
76
- parts.unshift(current.tagName.toLowerCase());
77
- }
78
- current = current.parentElement;
79
- }
80
- return parts.join(" > ");
81
- }
82
- function positionOverlay(overlay, rect) {
83
- Object.assign(overlay.style, {
84
- left: `${rect.left}px`,
85
- top: `${rect.top}px`,
86
- width: `${rect.width}px`,
87
- height: `${rect.height}px`,
88
- display: "block"
89
- });
90
- }
91
- function findSelectableElement(target) {
92
- let el = target;
93
- while (el && el !== document.body) {
94
- if (el.getAttribute("data-slot")) return el;
95
- el = el.parentElement;
96
- }
97
- return target;
98
- }
99
- const relevantProps = [
100
- "display",
101
- "position",
102
- "top",
103
- "right",
104
- "bottom",
105
- "left",
106
- "z-index",
107
- "overflow",
108
- "overflow-x",
109
- "overflow-y",
110
- "flex-direction",
111
- "flex-wrap",
112
- "justify-content",
113
- "align-items",
114
- "align-self",
115
- "flex-grow",
116
- "flex-shrink",
117
- "flex-basis",
118
- "order",
119
- "grid-template-columns",
120
- "grid-template-rows",
121
- "gap",
122
- "row-gap",
123
- "column-gap",
124
- "width",
125
- "height",
126
- "min-width",
127
- "min-height",
128
- "max-width",
129
- "max-height",
130
- "margin-top",
131
- "margin-right",
132
- "margin-bottom",
133
- "margin-left",
134
- "padding-top",
135
- "padding-right",
136
- "padding-bottom",
137
- "padding-left",
138
- "font-family",
139
- "font-size",
140
- "font-weight",
141
- "line-height",
142
- "letter-spacing",
143
- "text-align",
144
- "text-decoration",
145
- "text-transform",
146
- "color",
147
- "white-space",
148
- "background-color",
149
- "background-image",
150
- "background-size",
151
- "background-position",
152
- "border-top-width",
153
- "border-right-width",
154
- "border-bottom-width",
155
- "border-left-width",
156
- "border-style",
157
- "border-color",
158
- "border-top-left-radius",
159
- "border-top-right-radius",
160
- "border-bottom-right-radius",
161
- "border-bottom-left-radius",
162
- "opacity",
163
- "box-shadow",
164
- "transform",
165
- "transition"
166
- ];
167
- const inheritableProps = [
168
- "color",
169
- "font-family",
170
- "font-size",
171
- "font-weight",
172
- "line-height",
173
- "letter-spacing",
174
- "text-align",
175
- "text-transform",
176
- "white-space"
177
- ];
178
- function extractElementData(el) {
179
- const computed = getComputedStyle(el);
180
- const rect = el.getBoundingClientRect();
181
- const computedStyles = {};
182
- for (const prop of relevantProps) {
183
- computedStyles[prop] = computed.getPropertyValue(prop);
184
- }
185
- const parentComputedStyles = {};
186
- const parentEl = el.parentElement;
187
- if (parentEl) {
188
- const parentComputed = getComputedStyle(parentEl);
189
- for (const prop of inheritableProps) {
190
- parentComputedStyles[prop] = parentComputed.getPropertyValue(prop);
191
- }
192
- }
193
- const attributes = {};
194
- for (const attr of Array.from(el.attributes)) {
195
- if (attr.name.startsWith("data-")) {
196
- attributes[attr.name] = attr.value;
197
- }
198
- }
199
- let sourceFile = null;
200
- let sourceLine = null;
201
- let sourceCol = null;
202
- const dataSource = el.getAttribute("data-source");
203
- if (dataSource) {
204
- const lastColon = dataSource.lastIndexOf(":");
205
- const secondLastColon = dataSource.lastIndexOf(":", lastColon - 1);
206
- if (secondLastColon > 0) {
207
- sourceFile = dataSource.slice(0, secondLastColon);
208
- sourceLine = parseInt(dataSource.slice(secondLastColon + 1, lastColon), 10);
209
- sourceCol = parseInt(dataSource.slice(lastColon + 1), 10);
210
- }
211
- }
212
- let instanceSourceFile = null;
213
- let instanceSourceLine = null;
214
- let instanceSourceCol = null;
215
- let componentName = null;
216
- const instanceSource = el.getAttribute("data-instance-source");
217
- if (instanceSource && el.getAttribute("data-slot")) {
218
- const lc = instanceSource.lastIndexOf(":");
219
- const slc = instanceSource.lastIndexOf(":", lc - 1);
220
- if (slc > 0) {
221
- instanceSourceFile = instanceSource.slice(0, slc);
222
- instanceSourceLine = parseInt(instanceSource.slice(slc + 1, lc), 10);
223
- instanceSourceCol = parseInt(instanceSource.slice(lc + 1), 10);
224
- }
225
- const slot = el.getAttribute("data-slot") || "";
226
- componentName = slot.split("-").map((s2) => s2.charAt(0).toUpperCase() + s2.slice(1)).join("");
227
- }
228
- return {
229
- tag: el.tagName.toLowerCase(),
230
- className: (el.getAttribute("class") || "").trim(),
231
- computedStyles,
232
- parentComputedStyles,
233
- boundingRect: rect,
234
- domPath: getDomPath(el),
235
- textContent: (el.textContent || "").trim().slice(0, 100),
236
- attributes,
237
- sourceFile,
238
- sourceLine,
239
- sourceCol,
240
- instanceSourceFile,
241
- instanceSourceLine,
242
- instanceSourceCol,
243
- componentName
244
- };
245
- }
246
- function selectElement(el) {
247
- s.selectedElement = el;
248
- s.selectedDomPath = getDomPath(el);
249
- const data = extractElementData(el);
250
- if (s.selectedOverlay) {
251
- positionOverlay(s.selectedOverlay, data.boundingRect);
252
- }
253
- startOverlayTracking();
254
- window.parent.postMessage({ type: "tool:elementSelected", data }, "*");
255
- }
256
- function reselectCurrentElement() {
257
- if (!s.selectedDomPath) return;
258
- const el = document.querySelector(s.selectedDomPath);
259
- if (el) {
260
- s.selectedElement = el;
261
- const data = extractElementData(el);
262
- if (s.selectedOverlay) {
263
- positionOverlay(s.selectedOverlay, data.boundingRect);
264
- }
265
- window.parent.postMessage({ type: "tool:elementSelected", data }, "*");
266
- }
267
- }
268
- function startOverlayTracking() {
269
- if (s.overlayRafId) cancelAnimationFrame(s.overlayRafId);
270
- let lastRect = "";
271
- function tick() {
272
- if (s.selectedElement && s.selectedOverlay) {
273
- if (!document.contains(s.selectedElement)) {
274
- if (s.selectedDomPath) {
275
- const newEl = document.querySelector(s.selectedDomPath);
276
- if (newEl) {
277
- s.selectedElement = newEl;
278
- reselectCurrentElement();
279
- }
280
- }
281
- }
282
- if (s.selectedElement && document.contains(s.selectedElement)) {
283
- const rect = s.selectedElement.getBoundingClientRect();
284
- const key = `${rect.left},${rect.top},${rect.width},${rect.height}`;
285
- if (key !== lastRect) {
286
- lastRect = key;
287
- positionOverlay(s.selectedOverlay, rect);
288
- }
289
- }
290
- }
291
- s.overlayRafId = requestAnimationFrame(tick);
292
- }
293
- tick();
294
- }
295
- function onMouseMove(e) {
296
- if (!s.selectionMode || !s.highlightOverlay || !s.tooltip) return;
297
- const el = document.elementFromPoint(e.clientX, e.clientY);
298
- if (!el || el === s.highlightOverlay || el === s.tooltip || el === s.selectedOverlay) return;
299
- const selectable = findSelectableElement(el);
300
- if (selectable === s.hoveredElement) return;
301
- s.hoveredElement = selectable;
302
- const rect = selectable.getBoundingClientRect();
303
- positionOverlay(s.highlightOverlay, rect);
304
- const name = getElementName(selectable);
305
- s.tooltip.textContent = name;
306
- s.tooltip.style.display = "block";
307
- s.tooltip.style.left = `${rect.left}px`;
308
- s.tooltip.style.top = `${Math.max(0, rect.top - 24)}px`;
309
- }
310
- function onMouseLeave() {
311
- if (!s.highlightOverlay || !s.tooltip) return;
312
- s.highlightOverlay.style.display = "none";
313
- s.tooltip.style.display = "none";
314
- s.hoveredElement = null;
315
- }
316
- function onClick(e) {
317
- if (!s.selectionMode) return;
318
- e.preventDefault();
319
- e.stopPropagation();
320
- const el = document.elementFromPoint(e.clientX, e.clientY);
321
- if (!el || el === s.highlightOverlay || el === s.tooltip || el === s.selectedOverlay) return;
322
- const selectable = findSelectableElement(el);
323
- selectElement(selectable);
324
- }
325
- function onMessage(e) {
326
- const msg = e.data;
327
- if (!msg || !msg.type || !msg.type.startsWith("tool:")) return;
328
- switch (msg.type) {
329
- case "tool:enterSelectionMode":
330
- s.selectionMode = true;
331
- document.body.style.cursor = "crosshair";
332
- break;
333
- case "tool:exitSelectionMode":
334
- s.selectionMode = false;
335
- document.body.style.cursor = "";
336
- if (s.highlightOverlay) s.highlightOverlay.style.display = "none";
337
- if (s.tooltip) s.tooltip.style.display = "none";
338
- s.hoveredElement = null;
339
- break;
340
- case "tool:previewInlineStyle": {
341
- if (s.selectedElement && s.selectedElement instanceof HTMLElement) {
342
- const prop = msg.property;
343
- const value = msg.value;
344
- if (!s.inlineStyleBackups.has(prop)) {
345
- s.inlineStyleBackups.set(prop, s.selectedElement.style.getPropertyValue(prop));
346
- }
347
- s.selectedElement.style.setProperty(prop, value, "important");
348
- }
349
- break;
350
- }
351
- case "tool:revertInlineStyles": {
352
- if (s.selectedElement && s.selectedElement instanceof HTMLElement) {
353
- for (const [prop, original] of s.inlineStyleBackups) {
354
- if (original) {
355
- s.selectedElement.style.setProperty(prop, original);
356
- } else {
357
- s.selectedElement.style.removeProperty(prop);
358
- }
359
- }
360
- s.inlineStyleBackups.clear();
361
- }
362
- break;
363
- }
364
- case "tool:reselectElement":
365
- reselectCurrentElement();
366
- break;
367
- case "tool:setTheme":
368
- if (msg.theme === "dark") {
369
- document.documentElement.classList.add("dark");
370
- } else {
371
- document.documentElement.classList.remove("dark");
372
- }
373
- break;
374
- }
375
- }
376
- function notifyPathChanged() {
377
- const fullPath = window.location.pathname + window.location.search + window.location.hash;
378
- window.parent.postMessage({ type: "tool:pathChanged", path: fullPath }, "*");
379
- }
380
- document.addEventListener("mousemove", onMouseMove, true);
381
- document.addEventListener("mouseleave", onMouseLeave);
382
- document.addEventListener("click", onClick, true);
383
- window.addEventListener("message", onMessage);
384
- window.addEventListener("popstate", notifyPathChanged);
385
- window.parent.postMessage({ type: "tool:injectedReady" }, "*");
386
- notifyPathChanged();
387
- return () => {
388
- document.removeEventListener("mousemove", onMouseMove, true);
389
- document.removeEventListener("mouseleave", onMouseLeave);
390
- document.removeEventListener("click", onClick, true);
391
- window.removeEventListener("message", onMessage);
392
- window.removeEventListener("popstate", notifyPathChanged);
393
- if (s.overlayRafId) cancelAnimationFrame(s.overlayRafId);
394
- s.highlightOverlay?.remove();
395
- s.tooltip?.remove();
396
- s.selectedOverlay?.remove();
397
- };
398
- }, []);
399
- return null;
400
- }
401
- export {
402
- CodeCanvas
403
- };