@bitovi/vybit 0.4.4 → 0.4.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.
@@ -1,5 +1,1126 @@
1
1
  "use strict";
2
2
  (() => {
3
+ // node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs
4
+ var min = Math.min;
5
+ var max = Math.max;
6
+ var round = Math.round;
7
+ var createCoords = (v) => ({
8
+ x: v,
9
+ y: v
10
+ });
11
+ var oppositeSideMap = {
12
+ left: "right",
13
+ right: "left",
14
+ bottom: "top",
15
+ top: "bottom"
16
+ };
17
+ function evaluate(value, param) {
18
+ return typeof value === "function" ? value(param) : value;
19
+ }
20
+ function getSide(placement) {
21
+ return placement.split("-")[0];
22
+ }
23
+ function getAlignment(placement) {
24
+ return placement.split("-")[1];
25
+ }
26
+ function getOppositeAxis(axis) {
27
+ return axis === "x" ? "y" : "x";
28
+ }
29
+ function getAxisLength(axis) {
30
+ return axis === "y" ? "height" : "width";
31
+ }
32
+ function getSideAxis(placement) {
33
+ const firstChar = placement[0];
34
+ return firstChar === "t" || firstChar === "b" ? "y" : "x";
35
+ }
36
+ function getAlignmentAxis(placement) {
37
+ return getOppositeAxis(getSideAxis(placement));
38
+ }
39
+ function getAlignmentSides(placement, rects, rtl) {
40
+ if (rtl === void 0) {
41
+ rtl = false;
42
+ }
43
+ const alignment = getAlignment(placement);
44
+ const alignmentAxis = getAlignmentAxis(placement);
45
+ const length = getAxisLength(alignmentAxis);
46
+ let mainAlignmentSide = alignmentAxis === "x" ? alignment === (rtl ? "end" : "start") ? "right" : "left" : alignment === "start" ? "bottom" : "top";
47
+ if (rects.reference[length] > rects.floating[length]) {
48
+ mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
49
+ }
50
+ return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
51
+ }
52
+ function getExpandedPlacements(placement) {
53
+ const oppositePlacement = getOppositePlacement(placement);
54
+ return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
55
+ }
56
+ function getOppositeAlignmentPlacement(placement) {
57
+ return placement.includes("start") ? placement.replace("start", "end") : placement.replace("end", "start");
58
+ }
59
+ var lrPlacement = ["left", "right"];
60
+ var rlPlacement = ["right", "left"];
61
+ var tbPlacement = ["top", "bottom"];
62
+ var btPlacement = ["bottom", "top"];
63
+ function getSideList(side, isStart, rtl) {
64
+ switch (side) {
65
+ case "top":
66
+ case "bottom":
67
+ if (rtl) return isStart ? rlPlacement : lrPlacement;
68
+ return isStart ? lrPlacement : rlPlacement;
69
+ case "left":
70
+ case "right":
71
+ return isStart ? tbPlacement : btPlacement;
72
+ default:
73
+ return [];
74
+ }
75
+ }
76
+ function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
77
+ const alignment = getAlignment(placement);
78
+ let list = getSideList(getSide(placement), direction === "start", rtl);
79
+ if (alignment) {
80
+ list = list.map((side) => side + "-" + alignment);
81
+ if (flipAlignment) {
82
+ list = list.concat(list.map(getOppositeAlignmentPlacement));
83
+ }
84
+ }
85
+ return list;
86
+ }
87
+ function getOppositePlacement(placement) {
88
+ const side = getSide(placement);
89
+ return oppositeSideMap[side] + placement.slice(side.length);
90
+ }
91
+ function expandPaddingObject(padding) {
92
+ return {
93
+ top: 0,
94
+ right: 0,
95
+ bottom: 0,
96
+ left: 0,
97
+ ...padding
98
+ };
99
+ }
100
+ function getPaddingObject(padding) {
101
+ return typeof padding !== "number" ? expandPaddingObject(padding) : {
102
+ top: padding,
103
+ right: padding,
104
+ bottom: padding,
105
+ left: padding
106
+ };
107
+ }
108
+ function rectToClientRect(rect) {
109
+ const {
110
+ x,
111
+ y,
112
+ width,
113
+ height
114
+ } = rect;
115
+ return {
116
+ width,
117
+ height,
118
+ top: y,
119
+ left: x,
120
+ right: x + width,
121
+ bottom: y + height,
122
+ x,
123
+ y
124
+ };
125
+ }
126
+
127
+ // node_modules/@floating-ui/core/dist/floating-ui.core.mjs
128
+ function computeCoordsFromPlacement(_ref, placement, rtl) {
129
+ let {
130
+ reference,
131
+ floating
132
+ } = _ref;
133
+ const sideAxis = getSideAxis(placement);
134
+ const alignmentAxis = getAlignmentAxis(placement);
135
+ const alignLength = getAxisLength(alignmentAxis);
136
+ const side = getSide(placement);
137
+ const isVertical = sideAxis === "y";
138
+ const commonX = reference.x + reference.width / 2 - floating.width / 2;
139
+ const commonY = reference.y + reference.height / 2 - floating.height / 2;
140
+ const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;
141
+ let coords;
142
+ switch (side) {
143
+ case "top":
144
+ coords = {
145
+ x: commonX,
146
+ y: reference.y - floating.height
147
+ };
148
+ break;
149
+ case "bottom":
150
+ coords = {
151
+ x: commonX,
152
+ y: reference.y + reference.height
153
+ };
154
+ break;
155
+ case "right":
156
+ coords = {
157
+ x: reference.x + reference.width,
158
+ y: commonY
159
+ };
160
+ break;
161
+ case "left":
162
+ coords = {
163
+ x: reference.x - floating.width,
164
+ y: commonY
165
+ };
166
+ break;
167
+ default:
168
+ coords = {
169
+ x: reference.x,
170
+ y: reference.y
171
+ };
172
+ }
173
+ switch (getAlignment(placement)) {
174
+ case "start":
175
+ coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);
176
+ break;
177
+ case "end":
178
+ coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);
179
+ break;
180
+ }
181
+ return coords;
182
+ }
183
+ async function detectOverflow(state, options) {
184
+ var _await$platform$isEle;
185
+ if (options === void 0) {
186
+ options = {};
187
+ }
188
+ const {
189
+ x,
190
+ y,
191
+ platform: platform2,
192
+ rects,
193
+ elements,
194
+ strategy
195
+ } = state;
196
+ const {
197
+ boundary = "clippingAncestors",
198
+ rootBoundary = "viewport",
199
+ elementContext = "floating",
200
+ altBoundary = false,
201
+ padding = 0
202
+ } = evaluate(options, state);
203
+ const paddingObject = getPaddingObject(padding);
204
+ const altContext = elementContext === "floating" ? "reference" : "floating";
205
+ const element = elements[altBoundary ? altContext : elementContext];
206
+ const clippingClientRect = rectToClientRect(await platform2.getClippingRect({
207
+ element: ((_await$platform$isEle = await (platform2.isElement == null ? void 0 : platform2.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || await (platform2.getDocumentElement == null ? void 0 : platform2.getDocumentElement(elements.floating)),
208
+ boundary,
209
+ rootBoundary,
210
+ strategy
211
+ }));
212
+ const rect = elementContext === "floating" ? {
213
+ x,
214
+ y,
215
+ width: rects.floating.width,
216
+ height: rects.floating.height
217
+ } : rects.reference;
218
+ const offsetParent = await (platform2.getOffsetParent == null ? void 0 : platform2.getOffsetParent(elements.floating));
219
+ const offsetScale = await (platform2.isElement == null ? void 0 : platform2.isElement(offsetParent)) ? await (platform2.getScale == null ? void 0 : platform2.getScale(offsetParent)) || {
220
+ x: 1,
221
+ y: 1
222
+ } : {
223
+ x: 1,
224
+ y: 1
225
+ };
226
+ const elementClientRect = rectToClientRect(platform2.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform2.convertOffsetParentRelativeRectToViewportRelativeRect({
227
+ elements,
228
+ rect,
229
+ offsetParent,
230
+ strategy
231
+ }) : rect);
232
+ return {
233
+ top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,
234
+ bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,
235
+ left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,
236
+ right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x
237
+ };
238
+ }
239
+ var MAX_RESET_COUNT = 50;
240
+ var computePosition = async (reference, floating, config) => {
241
+ const {
242
+ placement = "bottom",
243
+ strategy = "absolute",
244
+ middleware = [],
245
+ platform: platform2
246
+ } = config;
247
+ const platformWithDetectOverflow = platform2.detectOverflow ? platform2 : {
248
+ ...platform2,
249
+ detectOverflow
250
+ };
251
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(floating));
252
+ let rects = await platform2.getElementRects({
253
+ reference,
254
+ floating,
255
+ strategy
256
+ });
257
+ let {
258
+ x,
259
+ y
260
+ } = computeCoordsFromPlacement(rects, placement, rtl);
261
+ let statefulPlacement = placement;
262
+ let resetCount = 0;
263
+ const middlewareData = {};
264
+ for (let i = 0; i < middleware.length; i++) {
265
+ const currentMiddleware = middleware[i];
266
+ if (!currentMiddleware) {
267
+ continue;
268
+ }
269
+ const {
270
+ name,
271
+ fn
272
+ } = currentMiddleware;
273
+ const {
274
+ x: nextX,
275
+ y: nextY,
276
+ data,
277
+ reset
278
+ } = await fn({
279
+ x,
280
+ y,
281
+ initialPlacement: placement,
282
+ placement: statefulPlacement,
283
+ strategy,
284
+ middlewareData,
285
+ rects,
286
+ platform: platformWithDetectOverflow,
287
+ elements: {
288
+ reference,
289
+ floating
290
+ }
291
+ });
292
+ x = nextX != null ? nextX : x;
293
+ y = nextY != null ? nextY : y;
294
+ middlewareData[name] = {
295
+ ...middlewareData[name],
296
+ ...data
297
+ };
298
+ if (reset && resetCount < MAX_RESET_COUNT) {
299
+ resetCount++;
300
+ if (typeof reset === "object") {
301
+ if (reset.placement) {
302
+ statefulPlacement = reset.placement;
303
+ }
304
+ if (reset.rects) {
305
+ rects = reset.rects === true ? await platform2.getElementRects({
306
+ reference,
307
+ floating,
308
+ strategy
309
+ }) : reset.rects;
310
+ }
311
+ ({
312
+ x,
313
+ y
314
+ } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));
315
+ }
316
+ i = -1;
317
+ }
318
+ }
319
+ return {
320
+ x,
321
+ y,
322
+ placement: statefulPlacement,
323
+ strategy,
324
+ middlewareData
325
+ };
326
+ };
327
+ var flip = function(options) {
328
+ if (options === void 0) {
329
+ options = {};
330
+ }
331
+ return {
332
+ name: "flip",
333
+ options,
334
+ async fn(state) {
335
+ var _middlewareData$arrow, _middlewareData$flip;
336
+ const {
337
+ placement,
338
+ middlewareData,
339
+ rects,
340
+ initialPlacement,
341
+ platform: platform2,
342
+ elements
343
+ } = state;
344
+ const {
345
+ mainAxis: checkMainAxis = true,
346
+ crossAxis: checkCrossAxis = true,
347
+ fallbackPlacements: specifiedFallbackPlacements,
348
+ fallbackStrategy = "bestFit",
349
+ fallbackAxisSideDirection = "none",
350
+ flipAlignment = true,
351
+ ...detectOverflowOptions
352
+ } = evaluate(options, state);
353
+ if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
354
+ return {};
355
+ }
356
+ const side = getSide(placement);
357
+ const initialSideAxis = getSideAxis(initialPlacement);
358
+ const isBasePlacement = getSide(initialPlacement) === initialPlacement;
359
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
360
+ const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));
361
+ const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== "none";
362
+ if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {
363
+ fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));
364
+ }
365
+ const placements2 = [initialPlacement, ...fallbackPlacements];
366
+ const overflow = await platform2.detectOverflow(state, detectOverflowOptions);
367
+ const overflows = [];
368
+ let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];
369
+ if (checkMainAxis) {
370
+ overflows.push(overflow[side]);
371
+ }
372
+ if (checkCrossAxis) {
373
+ const sides2 = getAlignmentSides(placement, rects, rtl);
374
+ overflows.push(overflow[sides2[0]], overflow[sides2[1]]);
375
+ }
376
+ overflowsData = [...overflowsData, {
377
+ placement,
378
+ overflows
379
+ }];
380
+ if (!overflows.every((side2) => side2 <= 0)) {
381
+ var _middlewareData$flip2, _overflowsData$filter;
382
+ const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
383
+ const nextPlacement = placements2[nextIndex];
384
+ if (nextPlacement) {
385
+ const ignoreCrossAxisOverflow = checkCrossAxis === "alignment" ? initialSideAxis !== getSideAxis(nextPlacement) : false;
386
+ if (!ignoreCrossAxisOverflow || // We leave the current main axis only if every placement on that axis
387
+ // overflows the main axis.
388
+ overflowsData.every((d) => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {
389
+ return {
390
+ data: {
391
+ index: nextIndex,
392
+ overflows: overflowsData
393
+ },
394
+ reset: {
395
+ placement: nextPlacement
396
+ }
397
+ };
398
+ }
399
+ }
400
+ let resetPlacement = (_overflowsData$filter = overflowsData.filter((d) => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;
401
+ if (!resetPlacement) {
402
+ switch (fallbackStrategy) {
403
+ case "bestFit": {
404
+ var _overflowsData$filter2;
405
+ const placement2 = (_overflowsData$filter2 = overflowsData.filter((d) => {
406
+ if (hasFallbackAxisSideDirection) {
407
+ const currentSideAxis = getSideAxis(d.placement);
408
+ return currentSideAxis === initialSideAxis || // Create a bias to the `y` side axis due to horizontal
409
+ // reading directions favoring greater width.
410
+ currentSideAxis === "y";
411
+ }
412
+ return true;
413
+ }).map((d) => [d.placement, d.overflows.filter((overflow2) => overflow2 > 0).reduce((acc, overflow2) => acc + overflow2, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];
414
+ if (placement2) {
415
+ resetPlacement = placement2;
416
+ }
417
+ break;
418
+ }
419
+ case "initialPlacement":
420
+ resetPlacement = initialPlacement;
421
+ break;
422
+ }
423
+ }
424
+ if (placement !== resetPlacement) {
425
+ return {
426
+ reset: {
427
+ placement: resetPlacement
428
+ }
429
+ };
430
+ }
431
+ }
432
+ return {};
433
+ }
434
+ };
435
+ };
436
+ var originSides = /* @__PURE__ */ new Set(["left", "top"]);
437
+ async function convertValueToCoords(state, options) {
438
+ const {
439
+ placement,
440
+ platform: platform2,
441
+ elements
442
+ } = state;
443
+ const rtl = await (platform2.isRTL == null ? void 0 : platform2.isRTL(elements.floating));
444
+ const side = getSide(placement);
445
+ const alignment = getAlignment(placement);
446
+ const isVertical = getSideAxis(placement) === "y";
447
+ const mainAxisMulti = originSides.has(side) ? -1 : 1;
448
+ const crossAxisMulti = rtl && isVertical ? -1 : 1;
449
+ const rawValue = evaluate(options, state);
450
+ let {
451
+ mainAxis,
452
+ crossAxis,
453
+ alignmentAxis
454
+ } = typeof rawValue === "number" ? {
455
+ mainAxis: rawValue,
456
+ crossAxis: 0,
457
+ alignmentAxis: null
458
+ } : {
459
+ mainAxis: rawValue.mainAxis || 0,
460
+ crossAxis: rawValue.crossAxis || 0,
461
+ alignmentAxis: rawValue.alignmentAxis
462
+ };
463
+ if (alignment && typeof alignmentAxis === "number") {
464
+ crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
465
+ }
466
+ return isVertical ? {
467
+ x: crossAxis * crossAxisMulti,
468
+ y: mainAxis * mainAxisMulti
469
+ } : {
470
+ x: mainAxis * mainAxisMulti,
471
+ y: crossAxis * crossAxisMulti
472
+ };
473
+ }
474
+ var offset = function(options) {
475
+ if (options === void 0) {
476
+ options = 0;
477
+ }
478
+ return {
479
+ name: "offset",
480
+ options,
481
+ async fn(state) {
482
+ var _middlewareData$offse, _middlewareData$arrow;
483
+ const {
484
+ x,
485
+ y,
486
+ placement,
487
+ middlewareData
488
+ } = state;
489
+ const diffCoords = await convertValueToCoords(state, options);
490
+ if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
491
+ return {};
492
+ }
493
+ return {
494
+ x: x + diffCoords.x,
495
+ y: y + diffCoords.y,
496
+ data: {
497
+ ...diffCoords,
498
+ placement
499
+ }
500
+ };
501
+ }
502
+ };
503
+ };
504
+
505
+ // node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs
506
+ function hasWindow() {
507
+ return typeof window !== "undefined";
508
+ }
509
+ function getNodeName(node) {
510
+ if (isNode(node)) {
511
+ return (node.nodeName || "").toLowerCase();
512
+ }
513
+ return "#document";
514
+ }
515
+ function getWindow(node) {
516
+ var _node$ownerDocument;
517
+ return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;
518
+ }
519
+ function getDocumentElement(node) {
520
+ var _ref;
521
+ return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;
522
+ }
523
+ function isNode(value) {
524
+ if (!hasWindow()) {
525
+ return false;
526
+ }
527
+ return value instanceof Node || value instanceof getWindow(value).Node;
528
+ }
529
+ function isElement(value) {
530
+ if (!hasWindow()) {
531
+ return false;
532
+ }
533
+ return value instanceof Element || value instanceof getWindow(value).Element;
534
+ }
535
+ function isHTMLElement(value) {
536
+ if (!hasWindow()) {
537
+ return false;
538
+ }
539
+ return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;
540
+ }
541
+ function isShadowRoot(value) {
542
+ if (!hasWindow() || typeof ShadowRoot === "undefined") {
543
+ return false;
544
+ }
545
+ return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
546
+ }
547
+ function isOverflowElement(element) {
548
+ const {
549
+ overflow,
550
+ overflowX,
551
+ overflowY,
552
+ display
553
+ } = getComputedStyle2(element);
554
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== "inline" && display !== "contents";
555
+ }
556
+ function isTableElement(element) {
557
+ return /^(table|td|th)$/.test(getNodeName(element));
558
+ }
559
+ function isTopLayer(element) {
560
+ try {
561
+ if (element.matches(":popover-open")) {
562
+ return true;
563
+ }
564
+ } catch (_e) {
565
+ }
566
+ try {
567
+ return element.matches(":modal");
568
+ } catch (_e) {
569
+ return false;
570
+ }
571
+ }
572
+ var willChangeRe = /transform|translate|scale|rotate|perspective|filter/;
573
+ var containRe = /paint|layout|strict|content/;
574
+ var isNotNone = (value) => !!value && value !== "none";
575
+ var isWebKitValue;
576
+ function isContainingBlock(elementOrCss) {
577
+ const css = isElement(elementOrCss) ? getComputedStyle2(elementOrCss) : elementOrCss;
578
+ return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || "") || containRe.test(css.contain || "");
579
+ }
580
+ function getContainingBlock(element) {
581
+ let currentNode = getParentNode(element);
582
+ while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {
583
+ if (isContainingBlock(currentNode)) {
584
+ return currentNode;
585
+ } else if (isTopLayer(currentNode)) {
586
+ return null;
587
+ }
588
+ currentNode = getParentNode(currentNode);
589
+ }
590
+ return null;
591
+ }
592
+ function isWebKit() {
593
+ if (isWebKitValue == null) {
594
+ isWebKitValue = typeof CSS !== "undefined" && CSS.supports && CSS.supports("-webkit-backdrop-filter", "none");
595
+ }
596
+ return isWebKitValue;
597
+ }
598
+ function isLastTraversableNode(node) {
599
+ return /^(html|body|#document)$/.test(getNodeName(node));
600
+ }
601
+ function getComputedStyle2(element) {
602
+ return getWindow(element).getComputedStyle(element);
603
+ }
604
+ function getNodeScroll(element) {
605
+ if (isElement(element)) {
606
+ return {
607
+ scrollLeft: element.scrollLeft,
608
+ scrollTop: element.scrollTop
609
+ };
610
+ }
611
+ return {
612
+ scrollLeft: element.scrollX,
613
+ scrollTop: element.scrollY
614
+ };
615
+ }
616
+ function getParentNode(node) {
617
+ if (getNodeName(node) === "html") {
618
+ return node;
619
+ }
620
+ const result = (
621
+ // Step into the shadow DOM of the parent of a slotted node.
622
+ node.assignedSlot || // DOM Element detected.
623
+ node.parentNode || // ShadowRoot detected.
624
+ isShadowRoot(node) && node.host || // Fallback.
625
+ getDocumentElement(node)
626
+ );
627
+ return isShadowRoot(result) ? result.host : result;
628
+ }
629
+ function getNearestOverflowAncestor(node) {
630
+ const parentNode = getParentNode(node);
631
+ if (isLastTraversableNode(parentNode)) {
632
+ return node.ownerDocument ? node.ownerDocument.body : node.body;
633
+ }
634
+ if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {
635
+ return parentNode;
636
+ }
637
+ return getNearestOverflowAncestor(parentNode);
638
+ }
639
+ function getOverflowAncestors(node, list, traverseIframes) {
640
+ var _node$ownerDocument2;
641
+ if (list === void 0) {
642
+ list = [];
643
+ }
644
+ if (traverseIframes === void 0) {
645
+ traverseIframes = true;
646
+ }
647
+ const scrollableAncestor = getNearestOverflowAncestor(node);
648
+ const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);
649
+ const win = getWindow(scrollableAncestor);
650
+ if (isBody) {
651
+ const frameElement = getFrameElement(win);
652
+ return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);
653
+ } else {
654
+ return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));
655
+ }
656
+ }
657
+ function getFrameElement(win) {
658
+ return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;
659
+ }
660
+
661
+ // node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs
662
+ function getCssDimensions(element) {
663
+ const css = getComputedStyle2(element);
664
+ let width = parseFloat(css.width) || 0;
665
+ let height = parseFloat(css.height) || 0;
666
+ const hasOffset = isHTMLElement(element);
667
+ const offsetWidth = hasOffset ? element.offsetWidth : width;
668
+ const offsetHeight = hasOffset ? element.offsetHeight : height;
669
+ const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;
670
+ if (shouldFallback) {
671
+ width = offsetWidth;
672
+ height = offsetHeight;
673
+ }
674
+ return {
675
+ width,
676
+ height,
677
+ $: shouldFallback
678
+ };
679
+ }
680
+ function unwrapElement(element) {
681
+ return !isElement(element) ? element.contextElement : element;
682
+ }
683
+ function getScale(element) {
684
+ const domElement = unwrapElement(element);
685
+ if (!isHTMLElement(domElement)) {
686
+ return createCoords(1);
687
+ }
688
+ const rect = domElement.getBoundingClientRect();
689
+ const {
690
+ width,
691
+ height,
692
+ $
693
+ } = getCssDimensions(domElement);
694
+ let x = ($ ? round(rect.width) : rect.width) / width;
695
+ let y = ($ ? round(rect.height) : rect.height) / height;
696
+ if (!x || !Number.isFinite(x)) {
697
+ x = 1;
698
+ }
699
+ if (!y || !Number.isFinite(y)) {
700
+ y = 1;
701
+ }
702
+ return {
703
+ x,
704
+ y
705
+ };
706
+ }
707
+ var noOffsets = /* @__PURE__ */ createCoords(0);
708
+ function getVisualOffsets(element) {
709
+ const win = getWindow(element);
710
+ if (!isWebKit() || !win.visualViewport) {
711
+ return noOffsets;
712
+ }
713
+ return {
714
+ x: win.visualViewport.offsetLeft,
715
+ y: win.visualViewport.offsetTop
716
+ };
717
+ }
718
+ function shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {
719
+ if (isFixed === void 0) {
720
+ isFixed = false;
721
+ }
722
+ if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {
723
+ return false;
724
+ }
725
+ return isFixed;
726
+ }
727
+ function getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {
728
+ if (includeScale === void 0) {
729
+ includeScale = false;
730
+ }
731
+ if (isFixedStrategy === void 0) {
732
+ isFixedStrategy = false;
733
+ }
734
+ const clientRect = element.getBoundingClientRect();
735
+ const domElement = unwrapElement(element);
736
+ let scale = createCoords(1);
737
+ if (includeScale) {
738
+ if (offsetParent) {
739
+ if (isElement(offsetParent)) {
740
+ scale = getScale(offsetParent);
741
+ }
742
+ } else {
743
+ scale = getScale(element);
744
+ }
745
+ }
746
+ const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);
747
+ let x = (clientRect.left + visualOffsets.x) / scale.x;
748
+ let y = (clientRect.top + visualOffsets.y) / scale.y;
749
+ let width = clientRect.width / scale.x;
750
+ let height = clientRect.height / scale.y;
751
+ if (domElement) {
752
+ const win = getWindow(domElement);
753
+ const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;
754
+ let currentWin = win;
755
+ let currentIFrame = getFrameElement(currentWin);
756
+ while (currentIFrame && offsetParent && offsetWin !== currentWin) {
757
+ const iframeScale = getScale(currentIFrame);
758
+ const iframeRect = currentIFrame.getBoundingClientRect();
759
+ const css = getComputedStyle2(currentIFrame);
760
+ const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;
761
+ const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;
762
+ x *= iframeScale.x;
763
+ y *= iframeScale.y;
764
+ width *= iframeScale.x;
765
+ height *= iframeScale.y;
766
+ x += left;
767
+ y += top;
768
+ currentWin = getWindow(currentIFrame);
769
+ currentIFrame = getFrameElement(currentWin);
770
+ }
771
+ }
772
+ return rectToClientRect({
773
+ width,
774
+ height,
775
+ x,
776
+ y
777
+ });
778
+ }
779
+ function getWindowScrollBarX(element, rect) {
780
+ const leftScroll = getNodeScroll(element).scrollLeft;
781
+ if (!rect) {
782
+ return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;
783
+ }
784
+ return rect.left + leftScroll;
785
+ }
786
+ function getHTMLOffset(documentElement, scroll) {
787
+ const htmlRect = documentElement.getBoundingClientRect();
788
+ const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);
789
+ const y = htmlRect.top + scroll.scrollTop;
790
+ return {
791
+ x,
792
+ y
793
+ };
794
+ }
795
+ function convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {
796
+ let {
797
+ elements,
798
+ rect,
799
+ offsetParent,
800
+ strategy
801
+ } = _ref;
802
+ const isFixed = strategy === "fixed";
803
+ const documentElement = getDocumentElement(offsetParent);
804
+ const topLayer = elements ? isTopLayer(elements.floating) : false;
805
+ if (offsetParent === documentElement || topLayer && isFixed) {
806
+ return rect;
807
+ }
808
+ let scroll = {
809
+ scrollLeft: 0,
810
+ scrollTop: 0
811
+ };
812
+ let scale = createCoords(1);
813
+ const offsets = createCoords(0);
814
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
815
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
816
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
817
+ scroll = getNodeScroll(offsetParent);
818
+ }
819
+ if (isOffsetParentAnElement) {
820
+ const offsetRect = getBoundingClientRect(offsetParent);
821
+ scale = getScale(offsetParent);
822
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
823
+ offsets.y = offsetRect.y + offsetParent.clientTop;
824
+ }
825
+ }
826
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
827
+ return {
828
+ width: rect.width * scale.x,
829
+ height: rect.height * scale.y,
830
+ x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
831
+ y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y
832
+ };
833
+ }
834
+ function getClientRects(element) {
835
+ return Array.from(element.getClientRects());
836
+ }
837
+ function getDocumentRect(element) {
838
+ const html = getDocumentElement(element);
839
+ const scroll = getNodeScroll(element);
840
+ const body = element.ownerDocument.body;
841
+ const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);
842
+ const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);
843
+ let x = -scroll.scrollLeft + getWindowScrollBarX(element);
844
+ const y = -scroll.scrollTop;
845
+ if (getComputedStyle2(body).direction === "rtl") {
846
+ x += max(html.clientWidth, body.clientWidth) - width;
847
+ }
848
+ return {
849
+ width,
850
+ height,
851
+ x,
852
+ y
853
+ };
854
+ }
855
+ var SCROLLBAR_MAX = 25;
856
+ function getViewportRect(element, strategy) {
857
+ const win = getWindow(element);
858
+ const html = getDocumentElement(element);
859
+ const visualViewport = win.visualViewport;
860
+ let width = html.clientWidth;
861
+ let height = html.clientHeight;
862
+ let x = 0;
863
+ let y = 0;
864
+ if (visualViewport) {
865
+ width = visualViewport.width;
866
+ height = visualViewport.height;
867
+ const visualViewportBased = isWebKit();
868
+ if (!visualViewportBased || visualViewportBased && strategy === "fixed") {
869
+ x = visualViewport.offsetLeft;
870
+ y = visualViewport.offsetTop;
871
+ }
872
+ }
873
+ const windowScrollbarX = getWindowScrollBarX(html);
874
+ if (windowScrollbarX <= 0) {
875
+ const doc = html.ownerDocument;
876
+ const body = doc.body;
877
+ const bodyStyles = getComputedStyle(body);
878
+ const bodyMarginInline = doc.compatMode === "CSS1Compat" ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;
879
+ const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);
880
+ if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {
881
+ width -= clippingStableScrollbarWidth;
882
+ }
883
+ } else if (windowScrollbarX <= SCROLLBAR_MAX) {
884
+ width += windowScrollbarX;
885
+ }
886
+ return {
887
+ width,
888
+ height,
889
+ x,
890
+ y
891
+ };
892
+ }
893
+ function getInnerBoundingClientRect(element, strategy) {
894
+ const clientRect = getBoundingClientRect(element, true, strategy === "fixed");
895
+ const top = clientRect.top + element.clientTop;
896
+ const left = clientRect.left + element.clientLeft;
897
+ const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);
898
+ const width = element.clientWidth * scale.x;
899
+ const height = element.clientHeight * scale.y;
900
+ const x = left * scale.x;
901
+ const y = top * scale.y;
902
+ return {
903
+ width,
904
+ height,
905
+ x,
906
+ y
907
+ };
908
+ }
909
+ function getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {
910
+ let rect;
911
+ if (clippingAncestor === "viewport") {
912
+ rect = getViewportRect(element, strategy);
913
+ } else if (clippingAncestor === "document") {
914
+ rect = getDocumentRect(getDocumentElement(element));
915
+ } else if (isElement(clippingAncestor)) {
916
+ rect = getInnerBoundingClientRect(clippingAncestor, strategy);
917
+ } else {
918
+ const visualOffsets = getVisualOffsets(element);
919
+ rect = {
920
+ x: clippingAncestor.x - visualOffsets.x,
921
+ y: clippingAncestor.y - visualOffsets.y,
922
+ width: clippingAncestor.width,
923
+ height: clippingAncestor.height
924
+ };
925
+ }
926
+ return rectToClientRect(rect);
927
+ }
928
+ function hasFixedPositionAncestor(element, stopNode) {
929
+ const parentNode = getParentNode(element);
930
+ if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {
931
+ return false;
932
+ }
933
+ return getComputedStyle2(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
934
+ }
935
+ function getClippingElementAncestors(element, cache) {
936
+ const cachedResult = cache.get(element);
937
+ if (cachedResult) {
938
+ return cachedResult;
939
+ }
940
+ let result = getOverflowAncestors(element, [], false).filter((el) => isElement(el) && getNodeName(el) !== "body");
941
+ let currentContainingBlockComputedStyle = null;
942
+ const elementIsFixed = getComputedStyle2(element).position === "fixed";
943
+ let currentNode = elementIsFixed ? getParentNode(element) : element;
944
+ while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {
945
+ const computedStyle = getComputedStyle2(currentNode);
946
+ const currentNodeIsContaining = isContainingBlock(currentNode);
947
+ if (!currentNodeIsContaining && computedStyle.position === "fixed") {
948
+ currentContainingBlockComputedStyle = null;
949
+ }
950
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === "static" && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === "absolute" || currentContainingBlockComputedStyle.position === "fixed") || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
951
+ if (shouldDropCurrentNode) {
952
+ result = result.filter((ancestor) => ancestor !== currentNode);
953
+ } else {
954
+ currentContainingBlockComputedStyle = computedStyle;
955
+ }
956
+ currentNode = getParentNode(currentNode);
957
+ }
958
+ cache.set(element, result);
959
+ return result;
960
+ }
961
+ function getClippingRect(_ref) {
962
+ let {
963
+ element,
964
+ boundary,
965
+ rootBoundary,
966
+ strategy
967
+ } = _ref;
968
+ const elementClippingAncestors = boundary === "clippingAncestors" ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);
969
+ const clippingAncestors = [...elementClippingAncestors, rootBoundary];
970
+ const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);
971
+ let top = firstRect.top;
972
+ let right = firstRect.right;
973
+ let bottom = firstRect.bottom;
974
+ let left = firstRect.left;
975
+ for (let i = 1; i < clippingAncestors.length; i++) {
976
+ const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);
977
+ top = max(rect.top, top);
978
+ right = min(rect.right, right);
979
+ bottom = min(rect.bottom, bottom);
980
+ left = max(rect.left, left);
981
+ }
982
+ return {
983
+ width: right - left,
984
+ height: bottom - top,
985
+ x: left,
986
+ y: top
987
+ };
988
+ }
989
+ function getDimensions(element) {
990
+ const {
991
+ width,
992
+ height
993
+ } = getCssDimensions(element);
994
+ return {
995
+ width,
996
+ height
997
+ };
998
+ }
999
+ function getRectRelativeToOffsetParent(element, offsetParent, strategy) {
1000
+ const isOffsetParentAnElement = isHTMLElement(offsetParent);
1001
+ const documentElement = getDocumentElement(offsetParent);
1002
+ const isFixed = strategy === "fixed";
1003
+ const rect = getBoundingClientRect(element, true, isFixed, offsetParent);
1004
+ let scroll = {
1005
+ scrollLeft: 0,
1006
+ scrollTop: 0
1007
+ };
1008
+ const offsets = createCoords(0);
1009
+ function setLeftRTLScrollbarOffset() {
1010
+ offsets.x = getWindowScrollBarX(documentElement);
1011
+ }
1012
+ if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
1013
+ if (getNodeName(offsetParent) !== "body" || isOverflowElement(documentElement)) {
1014
+ scroll = getNodeScroll(offsetParent);
1015
+ }
1016
+ if (isOffsetParentAnElement) {
1017
+ const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);
1018
+ offsets.x = offsetRect.x + offsetParent.clientLeft;
1019
+ offsets.y = offsetRect.y + offsetParent.clientTop;
1020
+ } else if (documentElement) {
1021
+ setLeftRTLScrollbarOffset();
1022
+ }
1023
+ }
1024
+ if (isFixed && !isOffsetParentAnElement && documentElement) {
1025
+ setLeftRTLScrollbarOffset();
1026
+ }
1027
+ const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
1028
+ const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
1029
+ const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
1030
+ return {
1031
+ x,
1032
+ y,
1033
+ width: rect.width,
1034
+ height: rect.height
1035
+ };
1036
+ }
1037
+ function isStaticPositioned(element) {
1038
+ return getComputedStyle2(element).position === "static";
1039
+ }
1040
+ function getTrueOffsetParent(element, polyfill) {
1041
+ if (!isHTMLElement(element) || getComputedStyle2(element).position === "fixed") {
1042
+ return null;
1043
+ }
1044
+ if (polyfill) {
1045
+ return polyfill(element);
1046
+ }
1047
+ let rawOffsetParent = element.offsetParent;
1048
+ if (getDocumentElement(element) === rawOffsetParent) {
1049
+ rawOffsetParent = rawOffsetParent.ownerDocument.body;
1050
+ }
1051
+ return rawOffsetParent;
1052
+ }
1053
+ function getOffsetParent(element, polyfill) {
1054
+ const win = getWindow(element);
1055
+ if (isTopLayer(element)) {
1056
+ return win;
1057
+ }
1058
+ if (!isHTMLElement(element)) {
1059
+ let svgOffsetParent = getParentNode(element);
1060
+ while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {
1061
+ if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {
1062
+ return svgOffsetParent;
1063
+ }
1064
+ svgOffsetParent = getParentNode(svgOffsetParent);
1065
+ }
1066
+ return win;
1067
+ }
1068
+ let offsetParent = getTrueOffsetParent(element, polyfill);
1069
+ while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {
1070
+ offsetParent = getTrueOffsetParent(offsetParent, polyfill);
1071
+ }
1072
+ if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {
1073
+ return win;
1074
+ }
1075
+ return offsetParent || getContainingBlock(element) || win;
1076
+ }
1077
+ var getElementRects = async function(data) {
1078
+ const getOffsetParentFn = this.getOffsetParent || getOffsetParent;
1079
+ const getDimensionsFn = this.getDimensions;
1080
+ const floatingDimensions = await getDimensionsFn(data.floating);
1081
+ return {
1082
+ reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),
1083
+ floating: {
1084
+ x: 0,
1085
+ y: 0,
1086
+ width: floatingDimensions.width,
1087
+ height: floatingDimensions.height
1088
+ }
1089
+ };
1090
+ };
1091
+ function isRTL(element) {
1092
+ return getComputedStyle2(element).direction === "rtl";
1093
+ }
1094
+ var platform = {
1095
+ convertOffsetParentRelativeRectToViewportRelativeRect,
1096
+ getDocumentElement,
1097
+ getClippingRect,
1098
+ getOffsetParent,
1099
+ getElementRects,
1100
+ getClientRects,
1101
+ getDimensions,
1102
+ getScale,
1103
+ isElement,
1104
+ isRTL
1105
+ };
1106
+ var offset2 = offset;
1107
+ var flip2 = flip;
1108
+ var computePosition2 = (reference, floating, options) => {
1109
+ const cache = /* @__PURE__ */ new Map();
1110
+ const mergedOptions = {
1111
+ platform,
1112
+ ...options
1113
+ };
1114
+ const platformWithCache = {
1115
+ ...mergedOptions.platform,
1116
+ _c: cache
1117
+ };
1118
+ return computePosition(reference, floating, {
1119
+ ...mergedOptions,
1120
+ platform: platformWithCache
1121
+ });
1122
+ };
1123
+
3
1124
  // overlay/src/ws.ts
4
1125
  var socket = null;
5
1126
  var connected = false;
@@ -557,6 +1678,7 @@ ${pad}</${tag}>`;
557
1678
  // overlay/src/patcher.ts
558
1679
  var previewState = null;
559
1680
  var previewStyleEl = null;
1681
+ var committedStyleEl = null;
560
1682
  var previewGeneration = 0;
561
1683
  async function applyPreview(elements, oldClass, newClass, serverOrigin) {
562
1684
  const gen = ++previewGeneration;
@@ -608,6 +1730,23 @@ ${pad}</${tag}>`;
608
1730
  function getPreviewState() {
609
1731
  return previewState;
610
1732
  }
1733
+ function commitPreview() {
1734
+ previewGeneration++;
1735
+ previewState = null;
1736
+ if (previewStyleEl) {
1737
+ const css = previewStyleEl.textContent || "";
1738
+ if (css) {
1739
+ if (!committedStyleEl) {
1740
+ committedStyleEl = document.createElement("style");
1741
+ committedStyleEl.setAttribute("data-tw-committed", "");
1742
+ document.head.appendChild(committedStyleEl);
1743
+ }
1744
+ committedStyleEl.textContent += css;
1745
+ }
1746
+ previewStyleEl.remove();
1747
+ previewStyleEl = null;
1748
+ }
1749
+ }
611
1750
 
612
1751
  // overlay/src/containers/PopoverContainer.ts
613
1752
  var PopoverContainer = class {
@@ -629,6 +1768,7 @@ ${pad}</${tag}>`;
629
1768
  z-index: 999999;
630
1769
  background: #1e1e2e;
631
1770
  box-shadow: -4px 0 24px rgba(0,0,0,0.3);
1771
+ pointer-events: auto;
632
1772
  `;
633
1773
  const iframe = document.createElement("iframe");
634
1774
  iframe.src = panelUrl;
@@ -685,6 +1825,7 @@ ${pad}</${tag}>`;
685
1825
  host.style.display = "flex";
686
1826
  host.style.flexDirection = "column";
687
1827
  host.style.overflow = "hidden";
1828
+ host.style.pointerEvents = "auto";
688
1829
  const handle = document.createElement("div");
689
1830
  handle.style.cssText = `
690
1831
  height: 28px;
@@ -792,10 +1933,37 @@ ${pad}</${tag}>`;
792
1933
  host = null;
793
1934
  originalPadding = "";
794
1935
  width = 380;
1936
+ pageWrapper = null;
1937
+ originalBodyOverflow = "";
795
1938
  open(panelUrl) {
796
1939
  if (this.host) return;
797
- this.originalPadding = document.documentElement.style.paddingRight;
798
- document.documentElement.style.paddingRight = `${this.width}px`;
1940
+ this.originalBodyOverflow = document.body.style.overflow;
1941
+ const wrapper = document.createElement("div");
1942
+ wrapper.id = "tw-page-wrapper";
1943
+ wrapper.style.cssText = `
1944
+ position: fixed;
1945
+ top: 0;
1946
+ left: 0;
1947
+ right: ${this.width}px;
1948
+ bottom: 0;
1949
+ overflow: auto;
1950
+ -webkit-overflow-scrolling: touch;
1951
+ background: transparent;
1952
+ z-index: 0;
1953
+ `;
1954
+ const bodyChildren = Array.from(document.body.childNodes);
1955
+ for (const node of bodyChildren) {
1956
+ if (node.id === "tw-visual-editor-host") continue;
1957
+ wrapper.appendChild(node);
1958
+ }
1959
+ const shadowHost2 = document.getElementById("tw-visual-editor-host");
1960
+ if (shadowHost2 && shadowHost2.parentNode) {
1961
+ shadowHost2.parentNode.insertBefore(wrapper, shadowHost2);
1962
+ } else {
1963
+ document.body.appendChild(wrapper);
1964
+ }
1965
+ document.body.style.overflow = "hidden";
1966
+ this.pageWrapper = wrapper;
799
1967
  const host = document.createElement("div");
800
1968
  host.className = "container-sidebar";
801
1969
  host.style.cssText = `
@@ -808,6 +1976,7 @@ ${pad}</${tag}>`;
808
1976
  background: #1e1e2e;
809
1977
  box-shadow: -4px 0 24px rgba(0,0,0,0.3);
810
1978
  display: flex;
1979
+ pointer-events: auto;
811
1980
  `;
812
1981
  const resizeHandle = document.createElement("div");
813
1982
  resizeHandle.style.cssText = `
@@ -835,7 +2004,20 @@ ${pad}</${tag}>`;
835
2004
  if (this.host) {
836
2005
  this.host.remove();
837
2006
  this.host = null;
838
- document.documentElement.style.paddingRight = this.originalPadding;
2007
+ if (this.pageWrapper) {
2008
+ const children = Array.from(this.pageWrapper.childNodes);
2009
+ const shadowHost2 = document.getElementById("tw-visual-editor-host");
2010
+ for (const node of children) {
2011
+ if (shadowHost2 && shadowHost2.parentNode) {
2012
+ shadowHost2.parentNode.insertBefore(node, shadowHost2);
2013
+ } else {
2014
+ document.body.appendChild(node);
2015
+ }
2016
+ }
2017
+ this.pageWrapper.remove();
2018
+ this.pageWrapper = null;
2019
+ }
2020
+ document.body.style.overflow = this.originalBodyOverflow || "";
839
2021
  }
840
2022
  }
841
2023
  isOpen() {
@@ -893,6 +2075,12 @@ ${pad}</${tag}>`;
893
2075
  var currentEquivalentNodes = [];
894
2076
  var currentTargetEl = null;
895
2077
  var currentBoundary = null;
2078
+ var currentInstances = [];
2079
+ var addingMode = false;
2080
+ var hoverOutlineEl = null;
2081
+ var hoverTooltipEl = null;
2082
+ var lastHoveredEl = null;
2083
+ var lastMoveTime = 0;
896
2084
  var containers;
897
2085
  var activeContainer;
898
2086
  var OVERLAY_CSS = `
@@ -900,37 +2088,47 @@ ${pad}</${tag}>`;
900
2088
  position: fixed;
901
2089
  bottom: 16px;
902
2090
  right: 16px;
903
- width: 36px;
904
- height: 36px;
2091
+ width: 40px;
2092
+ height: 40px;
905
2093
  border-radius: 50%;
906
- border: 1px solid #DFE2E2;
2094
+ border: 1.5px solid #DFE2E2;
907
2095
  cursor: pointer;
908
2096
  z-index: 999999;
909
- background: #F4F5F5;
910
- color: #687879;
911
- font-size: 18px;
912
- line-height: 1;
2097
+ background: #fff;
913
2098
  display: flex;
914
2099
  align-items: center;
915
2100
  justify-content: center;
916
- box-shadow: 0 2px 8px rgba(0,0,0,0.10);
917
- transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
2101
+ padding: 0;
2102
+ box-shadow: 0 2px 8px rgba(0,0,0,0.08);
2103
+ transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
2104
+ animation: vybit-breathe 3s ease-in-out infinite;
2105
+ pointer-events: auto;
2106
+ }
2107
+ @keyframes vybit-breathe {
2108
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(0,132,139,0), 0 2px 8px rgba(0,0,0,0.08); }
2109
+ 50% { box-shadow: 0 0 0 3px rgba(0,132,139,0.09), 0 0 12px rgba(0,132,139,0.07), 0 2px 8px rgba(0,0,0,0.08); }
918
2110
  }
919
2111
  .toggle-btn:hover {
920
- background: #E6E9E9;
921
2112
  border-color: #00848B;
922
- color: #00848B;
923
- }
924
- .toggle-btn.active {
925
- background: #F5532D;
926
- border-color: #F5532D;
927
- color: #fff;
928
- box-shadow: 0 0 0 4px rgba(245, 83, 45, 0.09), 0 2px 8px rgba(0,0,0,0.10);
2113
+ transform: scale(1.08);
2114
+ animation: none;
2115
+ box-shadow: 0 0 0 5px rgba(0,132,139,0.12), 0 0 18px rgba(0,132,139,0.12), 0 2px 8px rgba(0,0,0,0.10);
929
2116
  }
930
- .toggle-btn.active:hover {
931
- background: #C73D26;
932
- border-color: #C73D26;
2117
+ .toggle-btn:active { transform: scale(0.95); }
2118
+ .toggle-btn svg { display: block; }
2119
+ .toggle-btn .eb-fill { fill: #00848B; }
2120
+ @keyframes rainbow-eyes {
2121
+ 0% { fill: #ff4040; }
2122
+ 14% { fill: #ff9800; }
2123
+ 28% { fill: #ffee00; }
2124
+ 42% { fill: #3dff6e; }
2125
+ 57% { fill: #00bfff; }
2126
+ 71% { fill: #5050ff; }
2127
+ 85% { fill: #cc44ff; }
2128
+ 100% { fill: #ff4040; }
933
2129
  }
2130
+ .toggle-btn:hover .eb-eye-l { animation: rainbow-eyes 1.8s linear infinite; }
2131
+ .toggle-btn:hover .eb-eye-r { animation: rainbow-eyes 1.8s linear infinite; animation-delay: -0.45s; }
934
2132
  .toast {
935
2133
  position: fixed;
936
2134
  top: 16px;
@@ -950,38 +2148,208 @@ ${pad}</${tag}>`;
950
2148
  .toast.visible {
951
2149
  opacity: 1;
952
2150
  }
2151
+ @keyframes highlight-pulse {
2152
+ 0%, 100% { border-color: #00848B; box-shadow: 0 0 6px rgba(0,132,139,0.5); }
2153
+ 50% { border-color: #F5532D; box-shadow: 0 0 6px rgba(245,83,45,0.5); }
2154
+ }
953
2155
  .highlight-overlay {
954
2156
  position: fixed;
955
2157
  pointer-events: none;
956
- border: 2px solid rgba(0, 132, 139, 0.5);
957
- background: rgba(0, 132, 139, 0.08);
2158
+ border: 2px solid #00848B;
2159
+ border-radius: 2px;
2160
+ box-sizing: border-box;
958
2161
  z-index: 999998;
959
- transition: all 0.15s ease;
2162
+ animation: highlight-pulse 2s ease-in-out infinite;
960
2163
  }
961
- .draw-btn {
2164
+ /* Hover preview \u2014 lightweight outline shown while selection mode is active */
2165
+ .hover-target-outline {
962
2166
  position: fixed;
2167
+ pointer-events: none;
2168
+ border: 2px solid #00848B;
2169
+ border-radius: 2px;
2170
+ box-sizing: border-box;
963
2171
  z-index: 999999;
964
- width: 28px;
965
- height: 28px;
2172
+ transition: top 80ms ease, left 80ms ease, width 80ms ease, height 80ms ease;
2173
+ }
2174
+ .hover-tooltip {
2175
+ position: fixed;
2176
+ pointer-events: none;
2177
+ z-index: 1000000;
2178
+ background: #003D40;
2179
+ color: #E0F5F6;
2180
+ font-family: 'Inter', system-ui, sans-serif;
2181
+ font-size: 11px;
2182
+ line-height: 1;
2183
+ padding: 4px 8px;
2184
+ border-radius: 4px;
2185
+ white-space: nowrap;
2186
+ box-shadow: 0 2px 8px rgba(0,0,0,0.25);
2187
+ max-width: 280px;
2188
+ overflow: hidden;
2189
+ text-overflow: ellipsis;
2190
+ }
2191
+ .hover-tooltip .ht-dim { opacity: 0.55; }
2192
+ /* \u2500\u2500 Element toolbar \u2014 single connected dark bar \u2500\u2500 */
2193
+ .el-toolbar {
2194
+ position: fixed;
2195
+ z-index: 999999;
2196
+ display: flex;
2197
+ align-items: stretch;
2198
+ background: #003D40;
966
2199
  border-radius: 6px;
2200
+ overflow: hidden;
2201
+ box-shadow: 0 4px 16px rgba(0,0,0,0.28);
2202
+ pointer-events: auto;
2203
+ height: 30px;
2204
+ }
2205
+ .el-toolbar-sep {
2206
+ width: 1px;
2207
+ background: rgba(255,255,255,0.15);
2208
+ flex-shrink: 0;
2209
+ align-self: stretch;
2210
+ }
2211
+ /* Base style for all buttons inside the toolbar */
2212
+ .draw-btn, .el-pick-btn, .el-add-btn {
2213
+ background: transparent;
2214
+ border: none;
2215
+ border-radius: 0;
2216
+ box-shadow: none;
2217
+ color: #E0F5F6;
2218
+ font-family: 'Inter', system-ui, sans-serif;
2219
+ font-size: 11px;
2220
+ font-weight: 500;
2221
+ cursor: pointer;
2222
+ display: flex;
2223
+ align-items: center;
2224
+ justify-content: center;
2225
+ gap: 5px;
2226
+ padding: 0 10px;
2227
+ height: 30px;
2228
+ white-space: nowrap;
2229
+ transition: background 0.12s;
2230
+ pointer-events: auto;
2231
+ }
2232
+ .draw-btn { padding: 0 9px; }
2233
+ .el-pick-btn { gap: 3px; padding: 0 8px; font-size: 12px; font-weight: 600; letter-spacing: 0.01em; }
2234
+ .el-pick-btn svg { opacity: 0.7; flex-shrink: 0; }
2235
+ .el-add-btn { padding: 0 10px; font-size: 15px; font-weight: 400; }
2236
+ .draw-btn:hover, .el-pick-btn:hover, .el-add-btn:hover,
2237
+ .el-pick-btn.open {
2238
+ background: rgba(255,255,255,0.12);
2239
+ }
2240
+ /* \u2500\u2500 Instance picker popover \u2500\u2500 */
2241
+ .el-picker {
2242
+ position: fixed;
2243
+ z-index: 1000000;
2244
+ background: #fff;
967
2245
  border: 1px solid #DFE2E2;
968
- background: #F4F5F5;
2246
+ border-radius: 8px;
2247
+ box-shadow: 0 8px 28px rgba(0,0,0,0.14);
2248
+ min-width: 240px;
2249
+ max-width: 320px;
2250
+ font-family: 'Inter', system-ui, sans-serif;
2251
+ pointer-events: auto;
2252
+ overflow: hidden;
2253
+ }
2254
+ .el-picker-header {
2255
+ display: flex;
2256
+ align-items: center;
2257
+ justify-content: space-between;
2258
+ padding: 8px 12px 6px;
2259
+ border-bottom: 1px solid #DFE2E2;
2260
+ }
2261
+ .el-picker-title {
2262
+ font-size: 10px;
2263
+ font-weight: 700;
2264
+ text-transform: uppercase;
2265
+ letter-spacing: 0.05em;
2266
+ color: #687879;
2267
+ }
2268
+ .el-picker-actions {
2269
+ display: flex;
2270
+ gap: 8px;
2271
+ }
2272
+ .el-picker-actions a {
2273
+ font-size: 10px;
969
2274
  color: #00848B;
970
- font-size: 14px;
971
- line-height: 1;
2275
+ cursor: pointer;
2276
+ text-decoration: none;
2277
+ font-weight: 500;
2278
+ }
2279
+ .el-picker-actions a:hover { text-decoration: underline; }
2280
+ .el-picker-list {
2281
+ max-height: 240px;
2282
+ overflow-y: auto;
2283
+ padding: 4px 0;
2284
+ }
2285
+ .el-picker-row {
972
2286
  display: flex;
973
2287
  align-items: center;
974
- justify-content: center;
2288
+ gap: 8px;
2289
+ padding: 5px 12px;
975
2290
  cursor: pointer;
976
- box-shadow: 0 2px 8px rgba(0,0,0,0.12);
977
- transition: background 0.15s, border-color 0.15s, transform 0.1s;
978
- pointer-events: auto;
2291
+ transition: background 0.1s;
2292
+ }
2293
+ .el-picker-row:hover { background: rgba(0,132,139,0.05); }
2294
+ .el-picker-row input[type=checkbox] {
2295
+ accent-color: #00848B;
2296
+ width: 13px;
2297
+ height: 13px;
2298
+ flex-shrink: 0;
2299
+ cursor: pointer;
2300
+ }
2301
+ .el-picker-badge {
2302
+ width: 18px;
2303
+ height: 18px;
2304
+ border-radius: 50%;
2305
+ border: 1px solid #DFE2E2;
2306
+ background: #F4F5F5;
2307
+ color: #687879;
2308
+ font-size: 8px;
2309
+ font-weight: 700;
2310
+ display: flex;
2311
+ align-items: center;
2312
+ justify-content: center;
2313
+ flex-shrink: 0;
979
2314
  }
980
- .draw-btn:hover {
981
- background: #E6E9E9;
2315
+ .el-picker-badge.checked {
982
2316
  border-color: #00848B;
983
- transform: scale(1.08);
2317
+ background: rgba(0,132,139,0.08);
2318
+ color: #00848B;
2319
+ }
2320
+ .el-picker-label {
2321
+ flex: 1;
2322
+ font-size: 11px;
2323
+ color: #334041;
2324
+ overflow: hidden;
2325
+ text-overflow: ellipsis;
2326
+ white-space: nowrap;
2327
+ }
2328
+ .el-picker-tag {
2329
+ font-size: 9px;
2330
+ color: #A3ADAD;
2331
+ font-weight: 400;
984
2332
  }
2333
+ .el-picker-footer {
2334
+ padding: 6px 10px;
2335
+ border-top: 1px solid #DFE2E2;
2336
+ display: flex;
2337
+ justify-content: flex-end;
2338
+ }
2339
+ .el-picker-apply {
2340
+ height: 26px;
2341
+ padding: 0 12px;
2342
+ border-radius: 5px;
2343
+ border: none;
2344
+ background: #00848B;
2345
+ color: #fff;
2346
+ font-size: 11px;
2347
+ font-weight: 600;
2348
+ font-family: inherit;
2349
+ cursor: pointer;
2350
+ transition: background 0.15s;
2351
+ }
2352
+ .el-picker-apply:hover { background: #006E74; }
985
2353
  .draw-popover {
986
2354
  position: fixed;
987
2355
  z-index: 999999;
@@ -1053,52 +2421,305 @@ ${pad}</${tag}>`;
1053
2421
  const rect = el.getBoundingClientRect();
1054
2422
  const overlay = document.createElement("div");
1055
2423
  overlay.className = "highlight-overlay";
1056
- overlay.style.top = `${rect.top}px`;
1057
- overlay.style.left = `${rect.left}px`;
1058
- overlay.style.width = `${rect.width}px`;
1059
- overlay.style.height = `${rect.height}px`;
2424
+ overlay.style.top = `${rect.top - 3}px`;
2425
+ overlay.style.left = `${rect.left - 3}px`;
2426
+ overlay.style.width = `${rect.width + 6}px`;
2427
+ overlay.style.height = `${rect.height + 6}px`;
1060
2428
  shadowRoot.appendChild(overlay);
1061
2429
  }
1062
2430
  function clearHighlights() {
1063
2431
  shadowRoot.querySelectorAll(".highlight-overlay").forEach((el) => el.remove());
1064
2432
  removeDrawButton();
1065
2433
  }
1066
- var drawBtnEl = null;
2434
+ var toolbarEl = null;
1067
2435
  var drawPopoverEl = null;
2436
+ var pickerEl = null;
2437
+ var pickerCloseHandler = null;
2438
+ var selectedInstanceIndices = /* @__PURE__ */ new Set();
1068
2439
  function removeDrawButton() {
1069
- drawBtnEl?.remove();
1070
- drawBtnEl = null;
2440
+ toolbarEl?.remove();
2441
+ toolbarEl = null;
1071
2442
  drawPopoverEl?.remove();
1072
2443
  drawPopoverEl = null;
2444
+ pickerEl?.remove();
2445
+ pickerEl = null;
2446
+ }
2447
+ function clearHoverPreview() {
2448
+ hoverOutlineEl?.remove();
2449
+ hoverOutlineEl = null;
2450
+ hoverTooltipEl?.remove();
2451
+ hoverTooltipEl = null;
2452
+ lastHoveredEl = null;
2453
+ }
2454
+ function showHoverPreview(el, componentName) {
2455
+ const rect = el.getBoundingClientRect();
2456
+ if (!hoverOutlineEl) {
2457
+ hoverOutlineEl = document.createElement("div");
2458
+ hoverOutlineEl.className = "hover-target-outline";
2459
+ shadowRoot.appendChild(hoverOutlineEl);
2460
+ }
2461
+ hoverOutlineEl.style.top = `${rect.top - 3}px`;
2462
+ hoverOutlineEl.style.left = `${rect.left - 3}px`;
2463
+ hoverOutlineEl.style.width = `${rect.width + 6}px`;
2464
+ hoverOutlineEl.style.height = `${rect.height + 6}px`;
2465
+ if (!hoverTooltipEl) {
2466
+ hoverTooltipEl = document.createElement("div");
2467
+ hoverTooltipEl.className = "hover-tooltip";
2468
+ shadowRoot.appendChild(hoverTooltipEl);
2469
+ }
2470
+ const tag = el.tagName.toLowerCase();
2471
+ const cls = (typeof el.className === "string" ? el.className.trim().split(/\s+/)[0] : "") ?? "";
2472
+ hoverTooltipEl.innerHTML = `<span class="ht-dim">&lt;</span>${componentName}<span class="ht-dim">&gt;</span> <span class="ht-dim">${tag}${cls ? `.${cls}` : ""}</span>`;
2473
+ const tooltipHeight = 24;
2474
+ const ttTop = rect.top - tooltipHeight - 6;
2475
+ hoverTooltipEl.style.top = `${ttTop < 4 ? rect.bottom + 6 : ttTop}px`;
2476
+ hoverTooltipEl.style.left = `${Math.max(4, Math.min(rect.left, window.innerWidth - 200))}px`;
2477
+ }
2478
+ function mouseMoveHandler(e) {
2479
+ const now = Date.now();
2480
+ if (now - lastMoveTime < 16) return;
2481
+ lastMoveTime = now;
2482
+ const composed = e.composedPath();
2483
+ if (composed.some((n) => n === shadowHost)) {
2484
+ clearHoverPreview();
2485
+ return;
2486
+ }
2487
+ const target = e.target;
2488
+ if (!target || !(target instanceof HTMLElement)) {
2489
+ clearHoverPreview();
2490
+ return;
2491
+ }
2492
+ if (target === lastHoveredEl) return;
2493
+ lastHoveredEl = target;
2494
+ const rect = target.getBoundingClientRect();
2495
+ if (rect.width < 10 || rect.height < 10) {
2496
+ clearHoverPreview();
2497
+ return;
2498
+ }
2499
+ const fiber = getFiber(target);
2500
+ if (!fiber) {
2501
+ clearHoverPreview();
2502
+ return;
2503
+ }
2504
+ const boundary = findComponentBoundary(fiber);
2505
+ if (!boundary) {
2506
+ clearHoverPreview();
2507
+ return;
2508
+ }
2509
+ showHoverPreview(target, boundary.componentName);
2510
+ }
2511
+ var PENCIL_SVG = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2512
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
2513
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
2514
+ </svg>`;
2515
+ var CHEVRON_SVG = `<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
2516
+ async function positionWithFlip(anchor, floating, placement = "top-start") {
2517
+ const { x, y } = await computePosition2(anchor, floating, {
2518
+ placement,
2519
+ middleware: [offset2(6), flip2()]
2520
+ });
2521
+ floating.style.left = `${x}px`;
2522
+ floating.style.top = `${y}px`;
1073
2523
  }
1074
2524
  function showDrawButton(targetEl) {
1075
2525
  removeDrawButton();
1076
- const rect = targetEl.getBoundingClientRect();
1077
- const btn = document.createElement("button");
1078
- btn.className = "draw-btn";
1079
- btn.innerHTML = "\u270F";
1080
- btn.title = "Insert drawing canvas";
1081
- btn.style.left = `${Math.max(0, rect.left - 34)}px`;
1082
- btn.style.top = `${rect.top - 2}px`;
1083
- drawBtnEl = btn;
1084
- shadowRoot.appendChild(btn);
1085
- btn.addEventListener("click", (e) => {
2526
+ const allEquivalentNodes = [...currentEquivalentNodes];
2527
+ const instanceCount = allEquivalentNodes.length;
2528
+ const toolbar = document.createElement("div");
2529
+ toolbar.className = "el-toolbar";
2530
+ toolbar.style.left = "0px";
2531
+ toolbar.style.top = "0px";
2532
+ shadowRoot.appendChild(toolbar);
2533
+ toolbarEl = toolbar;
2534
+ const drawBtn = document.createElement("button");
2535
+ drawBtn.className = "draw-btn";
2536
+ drawBtn.innerHTML = PENCIL_SVG;
2537
+ drawBtn.title = "Insert drawing canvas";
2538
+ toolbar.appendChild(drawBtn);
2539
+ drawBtn.addEventListener("click", (e) => {
1086
2540
  e.stopPropagation();
2541
+ pickerEl?.remove();
2542
+ pickerEl = null;
1087
2543
  if (drawPopoverEl) {
1088
2544
  drawPopoverEl.remove();
1089
2545
  drawPopoverEl = null;
1090
2546
  } else {
1091
- showDrawPopover(btn);
2547
+ showDrawPopover(drawBtn);
1092
2548
  }
1093
2549
  });
2550
+ if (instanceCount > 1) {
2551
+ const sep = document.createElement("div");
2552
+ sep.className = "el-toolbar-sep";
2553
+ toolbar.appendChild(sep);
2554
+ const countBtn = document.createElement("button");
2555
+ countBtn.className = "el-pick-btn";
2556
+ const updateCountBtn = (n) => {
2557
+ countBtn.innerHTML = `${n} ${CHEVRON_SVG}`;
2558
+ };
2559
+ updateCountBtn(instanceCount);
2560
+ countBtn.title = "Select which instances to edit";
2561
+ toolbar.appendChild(countBtn);
2562
+ countBtn.addEventListener("click", (e) => {
2563
+ e.stopPropagation();
2564
+ drawPopoverEl?.remove();
2565
+ drawPopoverEl = null;
2566
+ if (pickerEl) {
2567
+ pickerEl.remove();
2568
+ pickerEl = null;
2569
+ countBtn.classList.remove("open");
2570
+ } else {
2571
+ countBtn.classList.add("open");
2572
+ showInstancePicker(
2573
+ countBtn,
2574
+ () => countBtn.classList.remove("open"),
2575
+ (indices) => {
2576
+ currentEquivalentNodes = indices.map((i) => allEquivalentNodes[i]).filter(Boolean);
2577
+ shadowRoot.querySelectorAll(".highlight-overlay").forEach((el) => el.remove());
2578
+ currentEquivalentNodes.forEach((n) => highlightElement(n));
2579
+ updateCountBtn(currentEquivalentNodes.length);
2580
+ }
2581
+ );
2582
+ }
2583
+ });
2584
+ const addBtn = document.createElement("button");
2585
+ addBtn.className = "el-add-btn";
2586
+ addBtn.textContent = "+";
2587
+ addBtn.title = "Add a different element to selection";
2588
+ toolbar.appendChild(addBtn);
2589
+ addBtn.addEventListener("click", (e) => {
2590
+ e.stopPropagation();
2591
+ pickerEl?.remove();
2592
+ pickerEl = null;
2593
+ drawPopoverEl?.remove();
2594
+ drawPopoverEl = null;
2595
+ addingMode = true;
2596
+ setSelectMode(true);
2597
+ showToast("Click another element to add it to the selection", 2500);
2598
+ });
2599
+ }
2600
+ positionWithFlip(targetEl, toolbar);
2601
+ }
2602
+ function showInstancePicker(anchorBtn, onClose, onApply) {
2603
+ if (pickerCloseHandler) {
2604
+ document.removeEventListener("click", pickerCloseHandler, { capture: true });
2605
+ pickerCloseHandler = null;
2606
+ }
2607
+ pickerEl?.remove();
2608
+ const instances = currentInstances;
2609
+ const allIndices = instances.map((_, i) => i);
2610
+ const selected = new Set(
2611
+ selectedInstanceIndices.size > 0 && selectedInstanceIndices.size <= instances.length ? [...selectedInstanceIndices].filter((i) => i < instances.length) : allIndices
2612
+ );
2613
+ const picker = document.createElement("div");
2614
+ picker.className = "el-picker";
2615
+ picker.style.left = "0px";
2616
+ picker.style.top = "0px";
2617
+ shadowRoot.appendChild(picker);
2618
+ pickerEl = picker;
2619
+ const header = document.createElement("div");
2620
+ header.className = "el-picker-header";
2621
+ const title = document.createElement("span");
2622
+ title.className = "el-picker-title";
2623
+ title.textContent = currentBoundary?.componentName ?? "Instances";
2624
+ const actions = document.createElement("div");
2625
+ actions.className = "el-picker-actions";
2626
+ const allLink = document.createElement("a");
2627
+ allLink.textContent = "All";
2628
+ const noneLink = document.createElement("a");
2629
+ noneLink.textContent = "None";
2630
+ actions.appendChild(allLink);
2631
+ actions.appendChild(noneLink);
2632
+ header.appendChild(title);
2633
+ header.appendChild(actions);
2634
+ picker.appendChild(header);
2635
+ const list = document.createElement("div");
2636
+ list.className = "el-picker-list";
2637
+ picker.appendChild(list);
2638
+ const checkboxes = [];
2639
+ function renderRows() {
2640
+ list.innerHTML = "";
2641
+ checkboxes.length = 0;
2642
+ instances.forEach((inst, i) => {
2643
+ const row = document.createElement("label");
2644
+ row.className = "el-picker-row";
2645
+ const cb = document.createElement("input");
2646
+ cb.type = "checkbox";
2647
+ cb.checked = selected.has(i);
2648
+ cb.addEventListener("change", () => {
2649
+ if (cb.checked) selected.add(i);
2650
+ else selected.delete(i);
2651
+ badge.className = "el-picker-badge" + (cb.checked ? " checked" : "");
2652
+ updateApply();
2653
+ });
2654
+ checkboxes.push(cb);
2655
+ const badge = document.createElement("span");
2656
+ badge.className = "el-picker-badge" + (cb.checked ? " checked" : "");
2657
+ badge.textContent = String(i + 1);
2658
+ const label = document.createElement("span");
2659
+ label.className = "el-picker-label";
2660
+ label.innerHTML = `${inst.label} <span class="el-picker-tag">${inst.parent}</span>`;
2661
+ row.appendChild(cb);
2662
+ row.appendChild(badge);
2663
+ row.appendChild(label);
2664
+ list.appendChild(row);
2665
+ });
2666
+ }
2667
+ renderRows();
2668
+ allLink.addEventListener("click", () => {
2669
+ instances.forEach((_, i) => selected.add(i));
2670
+ renderRows();
2671
+ updateApply();
2672
+ });
2673
+ noneLink.addEventListener("click", () => {
2674
+ selected.clear();
2675
+ renderRows();
2676
+ updateApply();
2677
+ });
2678
+ const footer = document.createElement("div");
2679
+ footer.className = "el-picker-footer";
2680
+ const applyBtn = document.createElement("button");
2681
+ applyBtn.className = "el-picker-apply";
2682
+ footer.appendChild(applyBtn);
2683
+ picker.appendChild(footer);
2684
+ function updateApply() {
2685
+ applyBtn.textContent = `Apply (${selected.size} selected)`;
2686
+ }
2687
+ updateApply();
2688
+ const removePicker = () => {
2689
+ if (pickerCloseHandler) {
2690
+ document.removeEventListener("click", pickerCloseHandler, { capture: true });
2691
+ pickerCloseHandler = null;
2692
+ }
2693
+ pickerEl?.remove();
2694
+ pickerEl = null;
2695
+ };
2696
+ applyBtn.addEventListener("click", (e) => {
2697
+ e.stopPropagation();
2698
+ const selectedIndices = [...selected];
2699
+ selectedInstanceIndices = new Set(selectedIndices);
2700
+ sendTo("panel", { type: "SELECT_MATCHING", indices: selectedIndices });
2701
+ onApply?.(selectedIndices);
2702
+ removePicker();
2703
+ onClose();
2704
+ });
2705
+ positionWithFlip(anchorBtn, picker);
2706
+ setTimeout(() => {
2707
+ pickerCloseHandler = (e) => {
2708
+ const path = e.composedPath();
2709
+ if (!path.includes(picker) && !path.includes(anchorBtn)) {
2710
+ removePicker();
2711
+ onClose();
2712
+ }
2713
+ };
2714
+ document.addEventListener("click", pickerCloseHandler, { capture: true });
2715
+ }, 0);
1094
2716
  }
1095
2717
  function showDrawPopover(anchorBtn) {
1096
2718
  drawPopoverEl?.remove();
1097
- const btnRect = anchorBtn.getBoundingClientRect();
1098
2719
  const popover = document.createElement("div");
1099
2720
  popover.className = "draw-popover";
1100
- popover.style.left = `${btnRect.right + 6}px`;
1101
- popover.style.top = `${btnRect.top}px`;
2721
+ popover.style.left = "0px";
2722
+ popover.style.top = "0px";
1102
2723
  const header = document.createElement("div");
1103
2724
  header.className = "draw-popover-header";
1104
2725
  header.textContent = "Insert Drawing Canvas";
@@ -1127,6 +2748,7 @@ ${pad}</${tag}>`;
1127
2748
  }
1128
2749
  drawPopoverEl = popover;
1129
2750
  shadowRoot.appendChild(popover);
2751
+ positionWithFlip(anchorBtn, popover, "top-start");
1130
2752
  const closeHandler = (e) => {
1131
2753
  const path = e.composedPath();
1132
2754
  if (!path.includes(popover) && !path.includes(anchorBtn)) {
@@ -1189,14 +2811,30 @@ ${pad}</${tag}>`;
1189
2811
  }
1190
2812
  const instances = findAllInstances(rootFiber, boundary.componentType);
1191
2813
  const path = getChildPath(boundary.componentFiber, fiber);
1192
- clearHighlights();
1193
- const equivalentNodes = [];
2814
+ const newNodes = [];
1194
2815
  for (const inst of instances) {
1195
2816
  const node = resolvePathToDOM(inst, path);
1196
- if (node) {
1197
- equivalentNodes.push(node);
1198
- highlightElement(node);
2817
+ if (node) newNodes.push(node);
2818
+ }
2819
+ if (addingMode && currentEquivalentNodes.length > 0) {
2820
+ addingMode = false;
2821
+ const merged = [...currentEquivalentNodes];
2822
+ for (const n of newNodes) {
2823
+ if (!merged.includes(n)) merged.push(n);
1199
2824
  }
2825
+ clearHighlights();
2826
+ merged.forEach((n) => highlightElement(n));
2827
+ currentEquivalentNodes = merged;
2828
+ selectedInstanceIndices = /* @__PURE__ */ new Set();
2829
+ if (currentTargetEl) showDrawButton(currentTargetEl);
2830
+ sendTo("panel", { type: "ELEMENT_SELECTED", componentName: currentBoundary?.componentName ?? boundary.componentName, instanceCount: merged.length, classes: currentTargetEl?.className ?? "", tailwindConfig: await fetchTailwindConfig() });
2831
+ return;
2832
+ }
2833
+ clearHighlights();
2834
+ const equivalentNodes = [];
2835
+ for (const node of newNodes) {
2836
+ equivalentNodes.push(node);
2837
+ highlightElement(node);
1200
2838
  }
1201
2839
  if (equivalentNodes.length <= 1) {
1202
2840
  const repeated = findInlineRepeatedNodes(fiber, boundary.componentFiber);
@@ -1219,6 +2857,16 @@ ${pad}</${tag}>`;
1219
2857
  currentEquivalentNodes = equivalentNodes;
1220
2858
  currentTargetEl = targetEl;
1221
2859
  currentBoundary = { componentName: boundary.componentName };
2860
+ selectedInstanceIndices = /* @__PURE__ */ new Set();
2861
+ currentInstances = instances.map((inst, i) => {
2862
+ const domNode = inst.stateNode instanceof HTMLElement ? inst.stateNode : null;
2863
+ const label = domNode ? (domNode.innerText || "").trim().slice(0, 40) || `#${i + 1}` : `#${i + 1}`;
2864
+ const parentFiber = inst.return;
2865
+ const parent = parentFiber?.type?.name ?? "";
2866
+ return { index: i, label, parent };
2867
+ });
2868
+ clearHoverPreview();
2869
+ setSelectMode(false);
1222
2870
  showDrawButton(targetEl);
1223
2871
  const panelUrl = `${SERVER_ORIGIN}/panel`;
1224
2872
  if (!activeContainer.isOpen()) {
@@ -1232,20 +2880,31 @@ ${pad}</${tag}>`;
1232
2880
  tailwindConfig: config
1233
2881
  });
1234
2882
  }
2883
+ function setSelectMode(on) {
2884
+ if (on) {
2885
+ document.documentElement.style.cursor = "crosshair";
2886
+ document.addEventListener("click", clickHandler, { capture: true });
2887
+ document.addEventListener("mousemove", mouseMoveHandler, { passive: true });
2888
+ } else {
2889
+ addingMode = false;
2890
+ document.documentElement.style.cursor = "";
2891
+ document.removeEventListener("click", clickHandler, { capture: true });
2892
+ document.removeEventListener("mousemove", mouseMoveHandler);
2893
+ clearHoverPreview();
2894
+ }
2895
+ sendTo("panel", { type: "SELECT_MODE_CHANGED", active: on });
2896
+ }
1235
2897
  function toggleInspect(btn) {
1236
2898
  active = !active;
1237
2899
  if (active) {
1238
2900
  btn.classList.add("active");
1239
- document.documentElement.style.cursor = "crosshair";
1240
- document.addEventListener("click", clickHandler, { capture: true });
1241
2901
  const panelUrl = `${SERVER_ORIGIN}/panel`;
1242
2902
  if (!activeContainer.isOpen()) {
1243
2903
  activeContainer.open(panelUrl);
1244
2904
  }
1245
2905
  } else {
1246
2906
  btn.classList.remove("active");
1247
- document.documentElement.style.cursor = "";
1248
- document.removeEventListener("click", clickHandler, { capture: true });
2907
+ setSelectMode(false);
1249
2908
  activeContainer.close();
1250
2909
  revertPreview();
1251
2910
  clearHighlights();
@@ -1435,7 +3094,7 @@ ${pad}</${tag}>`;
1435
3094
  function init() {
1436
3095
  shadowHost = document.createElement("div");
1437
3096
  shadowHost.id = "tw-visual-editor-host";
1438
- shadowHost.style.cssText = "position:fixed;z-index:2147483647;top:0;left:0;width:0;height:0;";
3097
+ shadowHost.style.cssText = "position:fixed;z-index:2147483647;top:0;left:0;width:0;height:0;pointer-events:none;";
1439
3098
  document.body.appendChild(shadowHost);
1440
3099
  shadowRoot = shadowHost.attachShadow({ mode: "open" });
1441
3100
  const style = document.createElement("style");
@@ -1450,13 +3109,27 @@ ${pad}</${tag}>`;
1450
3109
  activeContainer = containers[getDefaultContainer()];
1451
3110
  const btn = document.createElement("button");
1452
3111
  btn.className = "toggle-btn";
1453
- btn.textContent = "\u2295";
3112
+ btn.setAttribute("aria-label", "Open VyBit inspector");
3113
+ btn.innerHTML = `<svg width="26" height="27" viewBox="0 0 210 221" fill="none" xmlns="http://www.w3.org/2000/svg">
3114
+ <path class="eb-fill" d="M141.54 137.71L103.87 140.38C102.98 140.44 102.2 140.97 101.8 141.77C101.41 142.57 101.47 143.51 101.96 144.25C102.27 144.72 109.46 155.39 121.96 155.39C122.3 155.39 122.65 155.39 123 155.37C138.61 154.64 143.83 141.66 144.05 141.11C144.36 140.31 144.24 139.41 143.73 138.72C143.22 138.03 142.4 137.65 141.54 137.71Z"/>
3115
+ <path class="eb-eye-l eb-fill" d="M80.6401 93.03C76.7801 93.22 73.8 96.5 73.99 100.36L74.7501 115.96C74.9401 119.85 78.2701 122.84 82.1501 122.61C85.9801 122.38 88.9101 119.11 88.7301 115.28L87.9701 99.68C87.7801 95.82 84.5001 92.84 80.6401 93.03Z"/>
3116
+ <path class="eb-eye-r eb-fill" d="M149.46 96.67L150.32 111.72C150.54 115.58 153.85 118.53 157.71 118.31C161.57 118.09 164.52 114.78 164.3 110.92L163.44 95.87C163.22 92.03 159.94 89.08 156.09 89.28C152.22 89.48 149.24 92.79 149.47 96.67H149.46Z"/>
3117
+ <path class="eb-fill" d="M203.62 90.36C200.83 87.64 198.15 86.1 195.79 84.75C194 83.73 192.46 82.84 190.96 81.51C189.22 79.95 187.1 75.74 186.15 73.24C186.14 73.21 186.12 73.17 186.11 73.14C180.84 57.81 173.51 43.77 164.58 32.13C148.57 11.27 129.15 0.16 108.42 0C108.28 0 108.13 0 107.99 0C85.65 0 64.34 13.17 47.95 37.12C42.28 45.4 37.04 56.95 33.2 65.38C32.31 67.35 31.51 69.09 30.84 70.52C29.88 72.54 28.87 74.32 27.74 75.95L21.06 15.98C24.27 14.61 26.42 11.74 26.24 8.54C26 4.26 21.69 1.03 16.61 1.31C11.53 1.59 7.61002 5.29 7.85002 9.57C8.04002 12.85 10.61 15.51 14.09 16.45L16.67 85.85L16.29 86.08C13.19 87.96 9.98002 89.9 7.71002 92.09C4.65002 95.04 2.40002 99.48 1.21002 104.92C-1.62998 117.95 0.120019 138.77 10.82 143.95C18.87 147.85 25.1 154.71 28.83 163.79C42.17 198.91 71.91 219.98 108.4 220.16C108.56 220.16 108.71 220.16 108.87 220.16C133.9 220.16 156.3 210.08 171.97 191.74C183.26 178.53 190.59 161.68 193.54 142.92C194.26 139.76 197.48 136.44 200.62 133.23C204.14 129.62 207.78 125.89 209.22 121.16C210.85 115.82 209.93 96.53 203.62 90.36ZM173.3 73.25C176.99 83.04 179.72 93.27 181.36 103.35C183.29 115.23 183.53 126.81 182.18 137.69C180.99 142.99 176.46 157.5 161.58 165.93C141.26 177.45 110.38 180.84 88.16 174.01C63.16 166.32 48.04 142.7 47.72 110.85C47.39 78.09 63.77 70.45 80.58 65.42C101.92 59.04 133.9 57.44 153.39 61.79C163.19 63.98 168.32 67.53 170.9 70.13C172.08 71.32 172.83 72.4 173.3 73.25ZM162.85 183.94C149.31 199.79 130.66 208.15 108.89 208.15C108.75 208.15 108.61 208.15 108.46 208.15C77.09 207.99 51.5 189.77 40 159.41C39.96 159.32 39.93 159.22 39.89 159.13C36.77 151.59 32.28 145.21 26.65 140.22C26.61 140.17 26.57 140.13 26.53 140.08C23.64 137.25 24.55 133.1 24.74 131.41C26.16 118.65 22.59 108.63 21.57 106.52C20.4 104.1 19.23 105.15 19.49 106.56C19.78 108.18 20.09 110.5 20.28 112.89C21.07 122.72 19.28 131.47 17.02 133.03C16.74 133.22 16.46 133.27 16.16 133.19C16.12 133.17 16.08 133.15 16.04 133.13C13.44 131.87 10.36 119.2 12.92 107.46C13.86 103.16 15.4 101.31 16.02 100.71C17.32 99.45 19.95 97.87 22.48 96.33L23.24 95.87C32.05 90.52 37.38 84.66 41.66 75.64C42.36 74.17 43.18 72.36 44.1 70.33C47.54 62.75 52.75 51.3 57.82 43.89C71.91 23.31 89.7 12 107.96 12C108.07 12 108.18 12 108.29 12C133.67 12.19 154.63 33.4 167.85 60.64C164.47 58.82 160.16 57.16 154.65 55.93C134.31 51.39 101 53.03 78.82 59.67C59.32 65.5 41.33 75.74 41.68 110.91C42.03 145.51 58.73 171.25 86.35 179.75C94.55 182.27 103.85 183.49 113.4 183.49C131.42 183.49 150.35 179.17 164.49 171.16C169.1 168.55 172.84 165.45 175.87 162.21C172.6 170.28 168.23 177.61 162.81 183.95L162.85 183.94ZM197.75 117.65C197.4 118.8 196.34 120.21 195.01 121.7C194.91 115.06 194.32 108.28 193.21 101.43C192.95 99.84 192.67 98.26 192.37 96.69C193.34 97.32 194.27 98.01 195.19 98.9C196.86 101.11 198.85 113.73 197.76 117.66L197.75 117.65Z"/>
3118
+ </svg>`;
1454
3119
  btn.addEventListener("click", () => toggleInspect(btn));
1455
3120
  shadowRoot.appendChild(btn);
1456
3121
  const wsUrl = SERVER_ORIGIN.replace(/^http/, "ws");
1457
3122
  connect(wsUrl);
1458
3123
  onMessage((msg) => {
1459
- if (msg.type === "PATCH_PREVIEW" && currentEquivalentNodes.length > 0) {
3124
+ if (msg.type === "TOGGLE_SELECT_MODE") {
3125
+ if (msg.active) {
3126
+ setSelectMode(true);
3127
+ const panelUrl = `${SERVER_ORIGIN}/panel`;
3128
+ if (!activeContainer.isOpen()) activeContainer.open(panelUrl);
3129
+ } else {
3130
+ setSelectMode(false);
3131
+ }
3132
+ } else if (msg.type === "PATCH_PREVIEW" && currentEquivalentNodes.length > 0) {
1460
3133
  applyPreview(currentEquivalentNodes, msg.oldClass, msg.newClass, SERVER_ORIGIN);
1461
3134
  } else if (msg.type === "PATCH_REVERT") {
1462
3135
  revertPreview();
@@ -1492,6 +3165,7 @@ ${pad}</${tag}>`;
1492
3165
  }
1493
3166
  });
1494
3167
  showToast("Change staged");
3168
+ commitPreview();
1495
3169
  } else if (msg.type === "CLEAR_HIGHLIGHTS") {
1496
3170
  clearHighlights();
1497
3171
  } else if (msg.type === "SWITCH_CONTAINER") {
@@ -1531,6 +3205,12 @@ ${pad}</${tag}>`;
1531
3205
  if (last) last.remove();
1532
3206
  }
1533
3207
  });
3208
+ window.addEventListener("resize", () => {
3209
+ if (currentEquivalentNodes.length > 0) {
3210
+ shadowRoot.querySelectorAll(".highlight-overlay").forEach((el) => el.remove());
3211
+ currentEquivalentNodes.forEach((n) => highlightElement(n));
3212
+ }
3213
+ });
1534
3214
  window.addEventListener("overlay-ws-connected", () => {
1535
3215
  if (wasConnected) {
1536
3216
  showToast("Reconnected");