@designtools/next-plugin 0.1.8 → 0.1.10

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.
@@ -0,0 +1,1050 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/surface.tsx
22
+ var surface_exports = {};
23
+ __export(surface_exports, {
24
+ Surface: () => Surface
25
+ });
26
+ module.exports = __toCommonJS(surface_exports);
27
+ var import_react = require("react");
28
+ var import_react_dom = require("react-dom");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ function Surface() {
31
+ const stateRef = (0, import_react.useRef)({
32
+ selectionMode: false,
33
+ hoveredElement: null,
34
+ selectedElement: null,
35
+ selectedDomPath: null,
36
+ overlayRafId: null,
37
+ inlineStyleBackups: /* @__PURE__ */ new Map(),
38
+ tokenValueBackups: /* @__PURE__ */ new Map(),
39
+ tokenPreviewValues: /* @__PURE__ */ new Map(),
40
+ tokenPreviewStyle: null,
41
+ highlightOverlay: null,
42
+ tooltip: null,
43
+ selectedOverlay: null
44
+ });
45
+ const [previewComponent, setPreviewComponent] = (0, import_react.useState)(null);
46
+ const [previewCombinations, setPreviewCombinations] = (0, import_react.useState)([]);
47
+ const [previewDefaultChildren, setPreviewDefaultChildren] = (0, import_react.useState)("");
48
+ const [previewError, setPreviewError] = (0, import_react.useState)(null);
49
+ const [showPreview, setShowPreview] = (0, import_react.useState)(false);
50
+ const setPreviewRef = (0, import_react.useRef)({
51
+ setPreviewComponent,
52
+ setPreviewCombinations,
53
+ setPreviewDefaultChildren,
54
+ setPreviewError,
55
+ setShowPreview
56
+ });
57
+ setPreviewRef.current = {
58
+ setPreviewComponent,
59
+ setPreviewCombinations,
60
+ setPreviewDefaultChildren,
61
+ setPreviewError,
62
+ setShowPreview
63
+ };
64
+ (0, import_react.useEffect)(() => {
65
+ const s = stateRef.current;
66
+ s.highlightOverlay = document.createElement("div");
67
+ s.highlightOverlay.id = "tool-highlight";
68
+ Object.assign(s.highlightOverlay.style, {
69
+ position: "fixed",
70
+ pointerEvents: "none",
71
+ border: "2px solid #3b82f6",
72
+ backgroundColor: "rgba(59, 130, 246, 0.08)",
73
+ borderRadius: "2px",
74
+ zIndex: "99999",
75
+ display: "none",
76
+ transition: "all 0.1s ease"
77
+ });
78
+ document.body.appendChild(s.highlightOverlay);
79
+ s.tooltip = document.createElement("div");
80
+ s.tooltip.id = "tool-tooltip";
81
+ Object.assign(s.tooltip.style, {
82
+ position: "fixed",
83
+ pointerEvents: "none",
84
+ backgroundColor: "#1e1e2e",
85
+ color: "#cdd6f4",
86
+ padding: "3px 8px",
87
+ borderRadius: "4px",
88
+ fontSize: "11px",
89
+ fontFamily: "ui-monospace, monospace",
90
+ zIndex: "100000",
91
+ display: "none",
92
+ whiteSpace: "nowrap",
93
+ boxShadow: "0 2px 8px rgba(0,0,0,0.3)"
94
+ });
95
+ document.body.appendChild(s.tooltip);
96
+ s.selectedOverlay = document.createElement("div");
97
+ s.selectedOverlay.id = "tool-selected";
98
+ Object.assign(s.selectedOverlay.style, {
99
+ position: "fixed",
100
+ pointerEvents: "none",
101
+ border: "2px solid #f59e0b",
102
+ backgroundColor: "rgba(245, 158, 11, 0.06)",
103
+ borderRadius: "2px",
104
+ zIndex: "99998",
105
+ display: "none"
106
+ });
107
+ document.body.appendChild(s.selectedOverlay);
108
+ function getElementName(el) {
109
+ const slot = el.getAttribute("data-slot");
110
+ if (slot) return slot.charAt(0).toUpperCase() + slot.slice(1);
111
+ return `<${el.tagName.toLowerCase()}>`;
112
+ }
113
+ function getDomPath(el) {
114
+ const parts = [];
115
+ let current = el;
116
+ while (current && current !== document.body) {
117
+ const parent = current.parentElement;
118
+ if (parent) {
119
+ const idx = Array.from(parent.children).indexOf(current) + 1;
120
+ parts.unshift(`${current.tagName.toLowerCase()}:nth-child(${idx})`);
121
+ } else {
122
+ parts.unshift(current.tagName.toLowerCase());
123
+ }
124
+ current = current.parentElement;
125
+ }
126
+ return parts.join(" > ");
127
+ }
128
+ function positionOverlay(overlay, rect) {
129
+ Object.assign(overlay.style, {
130
+ left: `${rect.left}px`,
131
+ top: `${rect.top}px`,
132
+ width: `${rect.width}px`,
133
+ height: `${rect.height}px`,
134
+ display: "block"
135
+ });
136
+ }
137
+ function findSelectableElement(target) {
138
+ let el = target;
139
+ while (el && el !== document.body) {
140
+ if (el.getAttribute("data-slot")) return el;
141
+ el = el.parentElement;
142
+ }
143
+ return target;
144
+ }
145
+ const overlayIds = /* @__PURE__ */ new Set(["tool-highlight", "tool-tooltip", "tool-selected", "surface-token-preview"]);
146
+ const semanticTags = /* @__PURE__ */ new Set(["header", "main", "nav", "section", "article", "footer", "aside"]);
147
+ const skipTags = /* @__PURE__ */ new Set([
148
+ "html",
149
+ "body",
150
+ "head",
151
+ // document structure
152
+ "br",
153
+ "hr",
154
+ "wbr",
155
+ // void/formatting
156
+ "template",
157
+ "slot"
158
+ // shadow DOM
159
+ ]);
160
+ const frameworkPatterns = [
161
+ /^Fragment$/,
162
+ /^Suspense$/,
163
+ /^ErrorBoundary$/,
164
+ /^Provider$/,
165
+ /^Consumer$/,
166
+ /Context$/,
167
+ /^ForwardRef$/,
168
+ /^Memo$/,
169
+ /^Lazy$/,
170
+ // Next.js routing internals
171
+ /^InnerLayoutRouter$/,
172
+ /^OuterLayoutRouter$/,
173
+ /^LayoutRouter$/,
174
+ /^RenderFromTemplateContext$/,
175
+ /^TemplateContext$/,
176
+ /^RedirectBoundary$/,
177
+ /^RedirectErrorBoundary$/,
178
+ /^NotFoundBoundary$/,
179
+ /^LoadingBoundary$/,
180
+ /^HTTPAccessFallbackBoundary$/,
181
+ /^HTTPAccessFallbackErrorBoundary$/,
182
+ /^ClientPageRoot$/,
183
+ /^HotReload$/,
184
+ /^ReactDevOverlay$/,
185
+ /^PathnameContextProviderAdapter$/,
186
+ // Next.js App Router internals (segment tree)
187
+ /^SegmentViewNode$/,
188
+ /^SegmentTrieNode$/,
189
+ /^SegmentViewStateNode$/,
190
+ /^SegmentBoundaryTriggerNode$/,
191
+ /^SegmentStateProvider$/,
192
+ /^ScrollAndFocusHandler$/,
193
+ /^InnerScrollAndFocusHandler$/,
194
+ /^AppRouter$/,
195
+ /^Router$/,
196
+ /^Root$/,
197
+ /^ServerRoot$/,
198
+ /^RootErrorBoundary$/,
199
+ /^ErrorBoundaryHandler$/,
200
+ /^AppRouterAnnouncer$/,
201
+ /^HistoryUpdater$/,
202
+ /^RuntimeStyles$/,
203
+ /^DevRootHTTPAccessFallbackBoundary$/,
204
+ /^AppDevOverlayErrorBoundary$/,
205
+ /^ReplaySsrOnlyErrors$/,
206
+ /^HeadManagerContext$/,
207
+ /^Head$/,
208
+ /^MetadataOutlet$/,
209
+ /^AsyncMetadataOutlet$/,
210
+ /^__next_/
211
+ // All __next_ prefixed components
212
+ ];
213
+ function isFrameworkComponent(name) {
214
+ return frameworkPatterns.some((p) => p.test(name));
215
+ }
216
+ function getFiber(el) {
217
+ const key = Object.keys(el).find((k) => k.startsWith("__reactFiber$"));
218
+ return key ? el[key] : null;
219
+ }
220
+ function getDirectText(el) {
221
+ let text = "";
222
+ for (const node of Array.from(el.childNodes)) {
223
+ if (node.nodeType === Node.TEXT_NODE) {
224
+ text += (node.textContent || "").trim();
225
+ }
226
+ }
227
+ return text.slice(0, 40);
228
+ }
229
+ function inferScope(sourcePath) {
230
+ if (!sourcePath) return null;
231
+ const colonIdx = sourcePath.indexOf(":");
232
+ const file = colonIdx > 0 ? sourcePath.slice(0, colonIdx) : sourcePath;
233
+ if (/\/layout\.[tjsx]+$/i.test(file) || /^layout\.[tjsx]+$/i.test(file)) return "layout";
234
+ if (/\/page\.[tjsx]+$/i.test(file) || /^page\.[tjsx]+$/i.test(file)) return "page";
235
+ return null;
236
+ }
237
+ function getScopeForElement(el, parentScope) {
238
+ if (!el) return parentScope;
239
+ const instanceSource = el.getAttribute("data-instance-source");
240
+ const fromInstance = inferScope(instanceSource);
241
+ if (fromInstance) return fromInstance;
242
+ const source = el.getAttribute("data-source");
243
+ const fromSource = inferScope(source);
244
+ if (fromSource) return fromSource;
245
+ return parentScope;
246
+ }
247
+ function buildComponentTree(rootEl) {
248
+ const fiber = getFiber(rootEl);
249
+ if (!fiber) {
250
+ return buildDataSlotTree(rootEl);
251
+ }
252
+ let fiberRoot = fiber;
253
+ while (fiberRoot.return) fiberRoot = fiberRoot.return;
254
+ const results = [];
255
+ walkFiber(fiberRoot.child, results, null);
256
+ return results;
257
+ }
258
+ function walkFiber(fiber, siblings, parentScope) {
259
+ while (fiber) {
260
+ const node = processFiber(fiber, parentScope);
261
+ if (node) {
262
+ siblings.push(node);
263
+ } else {
264
+ if (fiber.child) {
265
+ let childScope = parentScope;
266
+ if (typeof fiber.type === "string" && fiber.stateNode instanceof Element) {
267
+ childScope = getScopeForElement(fiber.stateNode, parentScope);
268
+ } else if (typeof fiber.type === "function" || typeof fiber.type === "object") {
269
+ const hostEl = findOwnHostElement(fiber);
270
+ if (hostEl) {
271
+ childScope = getScopeForElement(hostEl, parentScope);
272
+ }
273
+ }
274
+ walkFiber(fiber.child, siblings, childScope);
275
+ }
276
+ }
277
+ fiber = fiber.sibling;
278
+ }
279
+ }
280
+ function processFiber(fiber, parentScope) {
281
+ if (typeof fiber.type === "string") {
282
+ return processHostFiber(fiber, parentScope);
283
+ }
284
+ if (typeof fiber.type === "function" || typeof fiber.type === "object") {
285
+ return processComponentFiber(fiber, parentScope);
286
+ }
287
+ return null;
288
+ }
289
+ function processHostFiber(fiber, parentScope) {
290
+ const tag = fiber.type;
291
+ const el = fiber.stateNode;
292
+ if (el && el.id && overlayIds.has(el.id)) return null;
293
+ if (["script", "style", "link", "noscript"].includes(tag)) return null;
294
+ const scope = getScopeForElement(el, parentScope);
295
+ const dataSlot = el?.getAttribute("data-slot") || null;
296
+ if (dataSlot) {
297
+ const name = dataSlot.split("-").map((s2) => s2.charAt(0).toUpperCase() + s2.slice(1)).join("");
298
+ const children = [];
299
+ if (fiber.child) walkFiber(fiber.child, children, scope);
300
+ return {
301
+ id: el ? getDomPath(el) : "",
302
+ name,
303
+ type: "component",
304
+ dataSlot,
305
+ source: el?.getAttribute("data-source") || null,
306
+ scope,
307
+ textContent: el ? getDirectText(el) : "",
308
+ children
309
+ };
310
+ }
311
+ if (semanticTags.has(tag)) {
312
+ const children = [];
313
+ if (fiber.child) walkFiber(fiber.child, children, scope);
314
+ const text = el ? getDirectText(el) : "";
315
+ return {
316
+ id: el ? getDomPath(el) : "",
317
+ name: `<${tag}>`,
318
+ type: "element",
319
+ dataSlot: null,
320
+ source: el?.getAttribute("data-source") || null,
321
+ scope,
322
+ textContent: text,
323
+ children
324
+ };
325
+ }
326
+ if (currentTreeMode === "dom" && el?.hasAttribute("data-source") && !skipTags.has(tag)) {
327
+ const children = [];
328
+ if (fiber.child) walkFiber(fiber.child, children, scope);
329
+ const text = el ? getDirectText(el) : "";
330
+ return {
331
+ id: getDomPath(el),
332
+ name: `<${tag}>`,
333
+ type: "element",
334
+ dataSlot: null,
335
+ source: el.getAttribute("data-source"),
336
+ scope,
337
+ textContent: text,
338
+ children
339
+ };
340
+ }
341
+ return null;
342
+ }
343
+ function processComponentFiber(fiber, parentScope) {
344
+ const type = fiber.type;
345
+ const name = type?.displayName || type?.name || null;
346
+ if (!name) return null;
347
+ if (isFrameworkComponent(name)) return null;
348
+ if (name === "Surface") return null;
349
+ const hostEl = findOwnHostElement(fiber);
350
+ const hasInstanceSource = hostEl?.getAttribute("data-instance-source");
351
+ const hasDataSlot = hostEl?.getAttribute("data-slot");
352
+ if (!hasInstanceSource && !hasDataSlot) return null;
353
+ const scope = getScopeForElement(hostEl, parentScope);
354
+ const dataSlot = hasDataSlot || null;
355
+ const children = [];
356
+ const hostFiber = dataSlot ? findHostFiber(fiber) : null;
357
+ const childFiber = hostFiber ? hostFiber.child : fiber.child;
358
+ if (childFiber) walkFiber(childFiber, children, scope);
359
+ if (children.length === 1 && !dataSlot && !(hostEl && getDirectText(hostEl))) {
360
+ const child = children[0];
361
+ if (child.type === "component") {
362
+ return child;
363
+ }
364
+ }
365
+ return {
366
+ id: hostEl ? getDomPath(hostEl) : "",
367
+ name,
368
+ type: "component",
369
+ dataSlot,
370
+ source: hostEl?.getAttribute("data-source") || null,
371
+ scope,
372
+ textContent: hostEl ? getDirectText(hostEl) : "",
373
+ children
374
+ };
375
+ }
376
+ function findHostFiber(fiber) {
377
+ let child = fiber.child;
378
+ while (child) {
379
+ if (child.stateNode instanceof Element) return child;
380
+ const tag = child.tag;
381
+ const isComponentBoundary = tag === 0 || tag === 1 || tag === 11 || tag === 14 || tag === 15;
382
+ if (!isComponentBoundary && child.child) {
383
+ const found = findHostFiber(child);
384
+ if (found) return found;
385
+ }
386
+ child = child.sibling;
387
+ }
388
+ return null;
389
+ }
390
+ function findOwnHostElement(fiber) {
391
+ let child = fiber.child;
392
+ while (child) {
393
+ if (child.stateNode instanceof Element) return child.stateNode;
394
+ const tag = child.tag;
395
+ const isComponentBoundary = tag === 0 || tag === 1 || tag === 11 || tag === 14 || tag === 15;
396
+ if (!isComponentBoundary && child.child) {
397
+ const found = findOwnHostElement(child);
398
+ if (found) return found;
399
+ }
400
+ child = child.sibling;
401
+ }
402
+ return null;
403
+ }
404
+ function buildDataSlotTree(root) {
405
+ const results = [];
406
+ for (const child of Array.from(root.children)) {
407
+ walkDomForSlots(child, results, null);
408
+ }
409
+ return results;
410
+ }
411
+ function walkDomForSlots(el, siblings, parentScope) {
412
+ if (el.id && overlayIds.has(el.id)) return;
413
+ const dataSlot = el.getAttribute("data-slot");
414
+ const tag = el.tagName.toLowerCase();
415
+ const scope = getScopeForElement(el, parentScope);
416
+ if (dataSlot) {
417
+ const name = dataSlot.split("-").map((s2) => s2.charAt(0).toUpperCase() + s2.slice(1)).join("");
418
+ const children = [];
419
+ for (const child of Array.from(el.children)) {
420
+ walkDomForSlots(child, children, scope);
421
+ }
422
+ siblings.push({
423
+ id: getDomPath(el),
424
+ name,
425
+ type: "component",
426
+ dataSlot,
427
+ source: el.getAttribute("data-source") || null,
428
+ scope,
429
+ textContent: getDirectText(el),
430
+ children
431
+ });
432
+ } else if (semanticTags.has(tag)) {
433
+ const children = [];
434
+ for (const child of Array.from(el.children)) {
435
+ walkDomForSlots(child, children, scope);
436
+ }
437
+ if (children.length > 0 || getDirectText(el)) {
438
+ siblings.push({
439
+ id: getDomPath(el),
440
+ name: `<${tag}>`,
441
+ type: "element",
442
+ dataSlot: null,
443
+ source: el.getAttribute("data-source") || null,
444
+ scope,
445
+ textContent: getDirectText(el),
446
+ children
447
+ });
448
+ }
449
+ } else {
450
+ for (const child of Array.from(el.children)) {
451
+ walkDomForSlots(child, siblings, scope);
452
+ }
453
+ }
454
+ }
455
+ let currentTreeMode = "components";
456
+ function sendComponentTree(mode) {
457
+ if (mode) currentTreeMode = mode;
458
+ const tree = buildComponentTree(document.body);
459
+ window.parent.postMessage({ type: "tool:componentTree", tree }, "*");
460
+ }
461
+ let debounceTimer = null;
462
+ function debouncedSendTree() {
463
+ if (debounceTimer) clearTimeout(debounceTimer);
464
+ debounceTimer = setTimeout(() => sendComponentTree(), 300);
465
+ }
466
+ const treeObserver = new MutationObserver(debouncedSendTree);
467
+ treeObserver.observe(document.body, { childList: true, subtree: true });
468
+ const relevantProps = [
469
+ "display",
470
+ "position",
471
+ "top",
472
+ "right",
473
+ "bottom",
474
+ "left",
475
+ "z-index",
476
+ "overflow",
477
+ "overflow-x",
478
+ "overflow-y",
479
+ "flex-direction",
480
+ "flex-wrap",
481
+ "justify-content",
482
+ "align-items",
483
+ "align-self",
484
+ "flex-grow",
485
+ "flex-shrink",
486
+ "flex-basis",
487
+ "order",
488
+ "grid-template-columns",
489
+ "grid-template-rows",
490
+ "gap",
491
+ "row-gap",
492
+ "column-gap",
493
+ "width",
494
+ "height",
495
+ "min-width",
496
+ "min-height",
497
+ "max-width",
498
+ "max-height",
499
+ "margin-top",
500
+ "margin-right",
501
+ "margin-bottom",
502
+ "margin-left",
503
+ "padding-top",
504
+ "padding-right",
505
+ "padding-bottom",
506
+ "padding-left",
507
+ "font-family",
508
+ "font-size",
509
+ "font-weight",
510
+ "line-height",
511
+ "letter-spacing",
512
+ "text-align",
513
+ "text-decoration",
514
+ "text-transform",
515
+ "color",
516
+ "white-space",
517
+ "background-color",
518
+ "background-image",
519
+ "background-size",
520
+ "background-position",
521
+ "border-top-width",
522
+ "border-right-width",
523
+ "border-bottom-width",
524
+ "border-left-width",
525
+ "border-style",
526
+ "border-color",
527
+ "border-top-left-radius",
528
+ "border-top-right-radius",
529
+ "border-bottom-right-radius",
530
+ "border-bottom-left-radius",
531
+ "opacity",
532
+ "box-shadow",
533
+ "transform",
534
+ "transition"
535
+ ];
536
+ const inheritableProps = [
537
+ "color",
538
+ "font-family",
539
+ "font-size",
540
+ "font-weight",
541
+ "line-height",
542
+ "letter-spacing",
543
+ "text-align",
544
+ "text-transform",
545
+ "white-space"
546
+ ];
547
+ function findComponentFiberAbove(el) {
548
+ const fiber = getFiber(el);
549
+ if (!fiber) return null;
550
+ let candidate = fiber.return;
551
+ while (candidate) {
552
+ const tag = candidate.tag;
553
+ if (tag === 0 || tag === 1 || tag === 11 || tag === 14 || tag === 15) {
554
+ if (findOwnHostElement(candidate) === el) return candidate;
555
+ }
556
+ candidate = candidate.return;
557
+ }
558
+ return null;
559
+ }
560
+ function extractFiberProps(fiber) {
561
+ const props = fiber?.memoizedProps;
562
+ if (!props || typeof props !== "object") return null;
563
+ const skipKeys = /* @__PURE__ */ new Set(["children", "ref", "key", "className", "style"]);
564
+ const result = {};
565
+ let count = 0;
566
+ for (const k of Object.keys(props)) {
567
+ if (skipKeys.has(k)) continue;
568
+ if (k.startsWith("data-")) continue;
569
+ const v = props[k];
570
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
571
+ result[k] = v;
572
+ count++;
573
+ }
574
+ }
575
+ return count > 0 ? result : null;
576
+ }
577
+ function extractElementData(el) {
578
+ const computed = getComputedStyle(el);
579
+ const rect = el.getBoundingClientRect();
580
+ const computedStyles = {};
581
+ for (const prop of relevantProps) {
582
+ computedStyles[prop] = computed.getPropertyValue(prop);
583
+ }
584
+ const parentComputedStyles = {};
585
+ const parentEl = el.parentElement;
586
+ if (parentEl) {
587
+ const parentComputed = getComputedStyle(parentEl);
588
+ for (const prop of inheritableProps) {
589
+ parentComputedStyles[prop] = parentComputed.getPropertyValue(prop);
590
+ }
591
+ }
592
+ const attributes = {};
593
+ for (const attr of Array.from(el.attributes)) {
594
+ if (attr.name.startsWith("data-")) {
595
+ attributes[attr.name] = attr.value;
596
+ }
597
+ }
598
+ let sourceFile = null;
599
+ let sourceLine = null;
600
+ let sourceCol = null;
601
+ const dataSource = el.getAttribute("data-source");
602
+ if (dataSource) {
603
+ const lastColon = dataSource.lastIndexOf(":");
604
+ const secondLastColon = dataSource.lastIndexOf(":", lastColon - 1);
605
+ if (secondLastColon > 0) {
606
+ sourceFile = dataSource.slice(0, secondLastColon);
607
+ sourceLine = parseInt(dataSource.slice(secondLastColon + 1, lastColon), 10);
608
+ sourceCol = parseInt(dataSource.slice(lastColon + 1), 10);
609
+ }
610
+ }
611
+ let instanceSourceFile = null;
612
+ let instanceSourceLine = null;
613
+ let instanceSourceCol = null;
614
+ let componentName = null;
615
+ let packageName = null;
616
+ const dataSlot = el.getAttribute("data-slot");
617
+ const instanceSource = el.getAttribute("data-instance-source");
618
+ if (instanceSource) {
619
+ const lc = instanceSource.lastIndexOf(":");
620
+ const slc = instanceSource.lastIndexOf(":", lc - 1);
621
+ if (slc > 0) {
622
+ instanceSourceFile = instanceSource.slice(0, slc);
623
+ instanceSourceLine = parseInt(instanceSource.slice(slc + 1, lc), 10);
624
+ instanceSourceCol = parseInt(instanceSource.slice(lc + 1), 10);
625
+ }
626
+ if (dataSlot) {
627
+ componentName = dataSlot.split("-").map((s2) => s2.charAt(0).toUpperCase() + s2.slice(1)).join("");
628
+ }
629
+ }
630
+ const compFiber = dataSlot || instanceSource ? findComponentFiberAbove(el) : null;
631
+ let fiberProps = null;
632
+ if (compFiber) {
633
+ fiberProps = extractFiberProps(compFiber);
634
+ if (!componentName && instanceSource) {
635
+ const name = compFiber.type?.displayName || compFiber.type?.name;
636
+ if (name) componentName = name;
637
+ }
638
+ const debugFile = compFiber._debugSource?.fileName;
639
+ if (debugFile) {
640
+ packageName = extractPackageName(debugFile);
641
+ }
642
+ }
643
+ if (!packageName && !sourceFile) {
644
+ const anyFiber = findComponentFiberAbove(el);
645
+ if (anyFiber) {
646
+ const debugFile = anyFiber._debugSource?.fileName;
647
+ if (debugFile) {
648
+ packageName = extractPackageName(debugFile);
649
+ }
650
+ }
651
+ }
652
+ return {
653
+ tag: el.tagName.toLowerCase(),
654
+ className: (el.getAttribute("class") || "").trim(),
655
+ computedStyles,
656
+ parentComputedStyles,
657
+ boundingRect: rect,
658
+ domPath: getDomPath(el),
659
+ textContent: (el.textContent || "").trim().slice(0, 100),
660
+ attributes,
661
+ sourceFile,
662
+ sourceLine,
663
+ sourceCol,
664
+ instanceSourceFile,
665
+ instanceSourceLine,
666
+ instanceSourceCol,
667
+ componentName,
668
+ packageName,
669
+ fiberProps
670
+ };
671
+ }
672
+ function extractPackageName(filePath) {
673
+ const nmIdx = filePath.lastIndexOf("node_modules/");
674
+ if (nmIdx === -1) return null;
675
+ const rest = filePath.slice(nmIdx + "node_modules/".length);
676
+ if (rest.startsWith("@")) {
677
+ const parts = rest.split("/");
678
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : null;
679
+ }
680
+ return rest.split("/")[0] || null;
681
+ }
682
+ function selectElement(el) {
683
+ s.selectedElement = el;
684
+ s.selectedDomPath = getDomPath(el);
685
+ const data = extractElementData(el);
686
+ if (s.selectedOverlay) {
687
+ positionOverlay(s.selectedOverlay, data.boundingRect);
688
+ }
689
+ startOverlayTracking();
690
+ window.parent.postMessage({ type: "tool:elementSelected", data }, "*");
691
+ }
692
+ function reselectCurrentElement() {
693
+ if (!s.selectedDomPath) return;
694
+ const el = document.querySelector(s.selectedDomPath);
695
+ if (el) {
696
+ s.selectedElement = el;
697
+ const data = extractElementData(el);
698
+ if (s.selectedOverlay) {
699
+ positionOverlay(s.selectedOverlay, data.boundingRect);
700
+ }
701
+ window.parent.postMessage({ type: "tool:elementSelected", data }, "*");
702
+ }
703
+ }
704
+ function startOverlayTracking() {
705
+ if (s.overlayRafId) cancelAnimationFrame(s.overlayRafId);
706
+ let lastRect = "";
707
+ function tick() {
708
+ if (s.selectedElement && s.selectedOverlay) {
709
+ if (!document.contains(s.selectedElement)) {
710
+ if (s.selectedDomPath) {
711
+ const newEl = document.querySelector(s.selectedDomPath);
712
+ if (newEl) {
713
+ s.selectedElement = newEl;
714
+ reselectCurrentElement();
715
+ }
716
+ }
717
+ }
718
+ if (s.selectedElement && document.contains(s.selectedElement)) {
719
+ const rect = s.selectedElement.getBoundingClientRect();
720
+ const key = `${rect.left},${rect.top},${rect.width},${rect.height}`;
721
+ if (key !== lastRect) {
722
+ lastRect = key;
723
+ positionOverlay(s.selectedOverlay, rect);
724
+ }
725
+ }
726
+ }
727
+ s.overlayRafId = requestAnimationFrame(tick);
728
+ }
729
+ tick();
730
+ }
731
+ function hideSelectionOverlays() {
732
+ if (s.highlightOverlay) s.highlightOverlay.style.display = "none";
733
+ if (s.tooltip) s.tooltip.style.display = "none";
734
+ if (s.selectedOverlay) s.selectedOverlay.style.display = "none";
735
+ s.hoveredElement = null;
736
+ }
737
+ function enterSelectionMode() {
738
+ s.selectionMode = true;
739
+ document.body.style.cursor = "crosshair";
740
+ }
741
+ function exitSelectionMode() {
742
+ s.selectionMode = false;
743
+ document.body.style.cursor = "";
744
+ if (s.highlightOverlay) s.highlightOverlay.style.display = "none";
745
+ if (s.tooltip) s.tooltip.style.display = "none";
746
+ s.hoveredElement = null;
747
+ }
748
+ function clearSelection() {
749
+ s.selectedElement = null;
750
+ s.selectedDomPath = null;
751
+ if (s.selectedOverlay) s.selectedOverlay.style.display = "none";
752
+ if (s.overlayRafId) {
753
+ cancelAnimationFrame(s.overlayRafId);
754
+ s.overlayRafId = null;
755
+ }
756
+ }
757
+ function onMouseMove(e) {
758
+ if (!s.selectionMode || !s.highlightOverlay || !s.tooltip) return;
759
+ const el = document.elementFromPoint(e.clientX, e.clientY);
760
+ if (!el || el === s.highlightOverlay || el === s.tooltip || el === s.selectedOverlay) return;
761
+ const selectable = findSelectableElement(el);
762
+ if (selectable === s.hoveredElement) return;
763
+ s.hoveredElement = selectable;
764
+ const rect = selectable.getBoundingClientRect();
765
+ positionOverlay(s.highlightOverlay, rect);
766
+ const name = getElementName(selectable);
767
+ s.tooltip.textContent = name;
768
+ s.tooltip.style.display = "block";
769
+ s.tooltip.style.left = `${rect.left}px`;
770
+ s.tooltip.style.top = `${Math.max(0, rect.top - 24)}px`;
771
+ }
772
+ function onMouseLeave() {
773
+ if (!s.highlightOverlay || !s.tooltip) return;
774
+ s.highlightOverlay.style.display = "none";
775
+ s.tooltip.style.display = "none";
776
+ s.hoveredElement = null;
777
+ }
778
+ function onClick(e) {
779
+ if (!s.selectionMode) return;
780
+ e.preventDefault();
781
+ e.stopPropagation();
782
+ const el = document.elementFromPoint(e.clientX, e.clientY);
783
+ if (!el || el === s.highlightOverlay || el === s.tooltip || el === s.selectedOverlay) return;
784
+ const selectable = findSelectableElement(el);
785
+ selectElement(selectable);
786
+ }
787
+ function onMessage(e) {
788
+ const msg = e.data;
789
+ if (!msg || !msg.type || !msg.type.startsWith("tool:")) return;
790
+ switch (msg.type) {
791
+ case "tool:enterSelectionMode":
792
+ enterSelectionMode();
793
+ break;
794
+ case "tool:exitSelectionMode":
795
+ exitSelectionMode();
796
+ break;
797
+ case "tool:clearSelection":
798
+ clearSelection();
799
+ break;
800
+ case "tool:previewInlineStyle": {
801
+ if (s.selectedElement && s.selectedElement instanceof HTMLElement) {
802
+ const prop = msg.property;
803
+ const value = msg.value;
804
+ if (!s.inlineStyleBackups.has(prop)) {
805
+ s.inlineStyleBackups.set(prop, s.selectedElement.style.getPropertyValue(prop));
806
+ }
807
+ s.selectedElement.style.setProperty(prop, value, "important");
808
+ }
809
+ break;
810
+ }
811
+ case "tool:revertInlineStyles": {
812
+ if (s.selectedElement && s.selectedElement instanceof HTMLElement) {
813
+ for (const [prop, original] of s.inlineStyleBackups) {
814
+ if (original) {
815
+ s.selectedElement.style.setProperty(prop, original);
816
+ } else {
817
+ s.selectedElement.style.removeProperty(prop);
818
+ }
819
+ }
820
+ s.inlineStyleBackups.clear();
821
+ }
822
+ break;
823
+ }
824
+ case "tool:previewTokenValue": {
825
+ const prop = msg.property;
826
+ const value = msg.value;
827
+ s.tokenPreviewValues.set(prop, value);
828
+ if (!s.tokenPreviewStyle) {
829
+ s.tokenPreviewStyle = document.createElement("style");
830
+ s.tokenPreviewStyle.id = "surface-token-preview";
831
+ document.head.appendChild(s.tokenPreviewStyle);
832
+ }
833
+ const cssRules = [];
834
+ for (const [k, v] of s.tokenPreviewValues) {
835
+ if (k.startsWith("--shadow")) {
836
+ const cls = k.slice(2);
837
+ cssRules.push(`.${cls}, [class*="${cls}"] { box-shadow: ${v} !important; }`);
838
+ } else {
839
+ cssRules.push(`*, *::before, *::after { ${k}: ${v} !important; }`);
840
+ }
841
+ }
842
+ s.tokenPreviewStyle.textContent = cssRules.join("\n");
843
+ break;
844
+ }
845
+ case "tool:revertTokenValues": {
846
+ if (s.tokenPreviewStyle) {
847
+ s.tokenPreviewStyle.remove();
848
+ s.tokenPreviewStyle = null;
849
+ }
850
+ s.tokenPreviewValues.clear();
851
+ s.tokenValueBackups.clear();
852
+ break;
853
+ }
854
+ case "tool:reselectElement":
855
+ reselectCurrentElement();
856
+ break;
857
+ case "tool:setTheme":
858
+ if (msg.theme === "dark") {
859
+ document.documentElement.classList.add("dark");
860
+ } else {
861
+ document.documentElement.classList.remove("dark");
862
+ }
863
+ break;
864
+ case "tool:requestComponentTree":
865
+ sendComponentTree(msg.mode || "components");
866
+ break;
867
+ case "tool:highlightByTreeId": {
868
+ const id = msg.id;
869
+ if (!id || !s.highlightOverlay || !s.tooltip) break;
870
+ const target = document.querySelector(id);
871
+ if (target) {
872
+ const rect = target.getBoundingClientRect();
873
+ positionOverlay(s.highlightOverlay, rect);
874
+ const name = getElementName(target);
875
+ s.tooltip.textContent = name;
876
+ s.tooltip.style.display = "block";
877
+ s.tooltip.style.left = `${rect.left}px`;
878
+ s.tooltip.style.top = `${Math.max(0, rect.top - 24)}px`;
879
+ }
880
+ break;
881
+ }
882
+ case "tool:clearHighlight":
883
+ if (s.highlightOverlay) s.highlightOverlay.style.display = "none";
884
+ if (s.tooltip) s.tooltip.style.display = "none";
885
+ break;
886
+ case "tool:selectByTreeId": {
887
+ const id = msg.id;
888
+ if (!id) break;
889
+ const target = document.querySelector(id);
890
+ if (target) {
891
+ const selectable = findSelectableElement(target);
892
+ selectElement(selectable);
893
+ }
894
+ break;
895
+ }
896
+ case "tool:selectParentInstance": {
897
+ if (!s.selectedElement) break;
898
+ let el = s.selectedElement.parentElement;
899
+ while (el && el !== document.body) {
900
+ if (el.getAttribute("data-instance-source")) {
901
+ selectElement(el);
902
+ break;
903
+ }
904
+ el = el.parentElement;
905
+ }
906
+ break;
907
+ }
908
+ case "tool:renderPreview": {
909
+ const { componentPath, exportName, combinations: combos, defaultChildren: children } = msg;
910
+ const currentRegistry = window.__DESIGNTOOLS_REGISTRY__;
911
+ if (!currentRegistry) {
912
+ setPreviewRef.current.setPreviewError("No component registry available. Ensure designtools-registry.ts is imported.");
913
+ setPreviewRef.current.setShowPreview(true);
914
+ return;
915
+ }
916
+ const loader = currentRegistry[componentPath];
917
+ if (!loader) {
918
+ setPreviewRef.current.setPreviewError(
919
+ `Component "${componentPath}" not found in registry. Available: ${Object.keys(currentRegistry).join(", ")}`
920
+ );
921
+ setPreviewRef.current.setShowPreview(true);
922
+ return;
923
+ }
924
+ exitSelectionMode();
925
+ hideSelectionOverlays();
926
+ loader().then((mod) => {
927
+ const Comp = mod[exportName] || mod.default;
928
+ if (!Comp) {
929
+ setPreviewRef.current.setPreviewError(`Export "${exportName}" not found in ${componentPath}`);
930
+ setPreviewRef.current.setShowPreview(true);
931
+ return;
932
+ }
933
+ setPreviewRef.current.setPreviewError(null);
934
+ setPreviewRef.current.setPreviewComponent(() => Comp);
935
+ setPreviewRef.current.setPreviewCombinations(combos || []);
936
+ setPreviewRef.current.setPreviewDefaultChildren(children || exportName);
937
+ setPreviewRef.current.setShowPreview(true);
938
+ window.parent.postMessage(
939
+ { type: "tool:previewReady", cellCount: (combos || []).length },
940
+ "*"
941
+ );
942
+ }).catch((err) => {
943
+ setPreviewRef.current.setPreviewError(`Failed to load component: ${err.message}`);
944
+ setPreviewRef.current.setShowPreview(true);
945
+ });
946
+ break;
947
+ }
948
+ case "tool:exitPreview": {
949
+ setPreviewRef.current.setShowPreview(false);
950
+ setPreviewRef.current.setPreviewComponent(null);
951
+ setPreviewRef.current.setPreviewCombinations([]);
952
+ setPreviewRef.current.setPreviewDefaultChildren("");
953
+ setPreviewRef.current.setPreviewError(null);
954
+ enterSelectionMode();
955
+ break;
956
+ }
957
+ }
958
+ }
959
+ function notifyPathChanged() {
960
+ const fullPath = window.location.pathname + window.location.search + window.location.hash;
961
+ window.parent.postMessage({ type: "tool:pathChanged", path: fullPath }, "*");
962
+ }
963
+ document.addEventListener("mousemove", onMouseMove, true);
964
+ document.addEventListener("mouseleave", onMouseLeave);
965
+ document.addEventListener("click", onClick, true);
966
+ window.addEventListener("message", onMessage);
967
+ window.addEventListener("popstate", notifyPathChanged);
968
+ window.parent.postMessage({ type: "tool:injectedReady" }, "*");
969
+ notifyPathChanged();
970
+ return () => {
971
+ document.removeEventListener("mousemove", onMouseMove, true);
972
+ document.removeEventListener("mouseleave", onMouseLeave);
973
+ document.removeEventListener("click", onClick, true);
974
+ window.removeEventListener("message", onMessage);
975
+ window.removeEventListener("popstate", notifyPathChanged);
976
+ treeObserver.disconnect();
977
+ if (debounceTimer) clearTimeout(debounceTimer);
978
+ if (s.overlayRafId) cancelAnimationFrame(s.overlayRafId);
979
+ s.tokenPreviewStyle?.remove();
980
+ s.highlightOverlay?.remove();
981
+ s.tooltip?.remove();
982
+ s.selectedOverlay?.remove();
983
+ };
984
+ }, []);
985
+ if (!showPreview) return null;
986
+ if (previewError) {
987
+ return (0, import_react_dom.createPortal)(
988
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
989
+ position: "fixed",
990
+ inset: 0,
991
+ zIndex: 999999,
992
+ background: "var(--background, white)",
993
+ overflow: "auto",
994
+ padding: 32
995
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--destructive, #ef4444)", fontFamily: "monospace", fontSize: 14 }, children: previewError }) }),
996
+ document.body
997
+ );
998
+ }
999
+ if (!previewComponent) {
1000
+ return (0, import_react_dom.createPortal)(
1001
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1002
+ position: "fixed",
1003
+ inset: 0,
1004
+ zIndex: 999999,
1005
+ background: "var(--background, white)",
1006
+ overflow: "auto",
1007
+ padding: 32
1008
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "var(--muted-foreground, #888)", fontFamily: "inherit", fontSize: 14 }, children: "Loading component..." }) }),
1009
+ document.body
1010
+ );
1011
+ }
1012
+ const Component = previewComponent;
1013
+ return (0, import_react_dom.createPortal)(
1014
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1015
+ position: "fixed",
1016
+ inset: 0,
1017
+ zIndex: 999999,
1018
+ background: "var(--background, white)",
1019
+ overflow: "auto",
1020
+ padding: 32
1021
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1022
+ display: "grid",
1023
+ gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))",
1024
+ gap: 24
1025
+ }, children: previewCombinations.map((combo, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
1026
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1027
+ fontSize: 11,
1028
+ fontWeight: 600,
1029
+ color: "var(--muted-foreground, #888)",
1030
+ textTransform: "uppercase",
1031
+ letterSpacing: "0.05em"
1032
+ }, children: combo.label }),
1033
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
1034
+ padding: 16,
1035
+ border: "1px solid var(--border, #e5e7eb)",
1036
+ borderRadius: 8,
1037
+ display: "flex",
1038
+ alignItems: "center",
1039
+ justifyContent: "center",
1040
+ minHeight: 64,
1041
+ background: "var(--card, var(--background, #fff))"
1042
+ }, children: (0, import_react.createElement)(Component, combo.props, previewDefaultChildren) })
1043
+ ] }, i)) }) }),
1044
+ document.body
1045
+ );
1046
+ }
1047
+ // Annotate the CommonJS export names for ESM import in node:
1048
+ 0 && (module.exports = {
1049
+ Surface
1050
+ });