@lukso/up-connector 0.4.0-dev.a8c9315

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.
Files changed (109) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +280 -0
  3. package/dist/account-modal.cjs +9 -0
  4. package/dist/account-modal.cjs.map +1 -0
  5. package/dist/account-modal.d.cts +16 -0
  6. package/dist/account-modal.d.ts +16 -0
  7. package/dist/account-modal.js +9 -0
  8. package/dist/account-modal.js.map +1 -0
  9. package/dist/auto-setup.cjs +17 -0
  10. package/dist/auto-setup.cjs.map +1 -0
  11. package/dist/auto-setup.d.cts +123 -0
  12. package/dist/auto-setup.d.ts +123 -0
  13. package/dist/auto-setup.js +17 -0
  14. package/dist/auto-setup.js.map +1 -0
  15. package/dist/avatar-CmUCtW_w.d.cts +205 -0
  16. package/dist/avatar-CmUCtW_w.d.ts +205 -0
  17. package/dist/avatar.cjs +12 -0
  18. package/dist/avatar.cjs.map +1 -0
  19. package/dist/avatar.d.cts +1 -0
  20. package/dist/avatar.d.ts +1 -0
  21. package/dist/avatar.js +12 -0
  22. package/dist/avatar.js.map +1 -0
  23. package/dist/backup-modal.cjs +9 -0
  24. package/dist/backup-modal.cjs.map +1 -0
  25. package/dist/backup-modal.d.cts +41 -0
  26. package/dist/backup-modal.d.ts +41 -0
  27. package/dist/backup-modal.js +9 -0
  28. package/dist/backup-modal.js.map +1 -0
  29. package/dist/chunk-3SGSPHOZ.js +595 -0
  30. package/dist/chunk-3SGSPHOZ.js.map +1 -0
  31. package/dist/chunk-6AYZOIFY.js +181 -0
  32. package/dist/chunk-6AYZOIFY.js.map +1 -0
  33. package/dist/chunk-6N35TCFT.js +852 -0
  34. package/dist/chunk-6N35TCFT.js.map +1 -0
  35. package/dist/chunk-7ETKG6KR.cjs +387 -0
  36. package/dist/chunk-7ETKG6KR.cjs.map +1 -0
  37. package/dist/chunk-EUXUH3YW.js +15 -0
  38. package/dist/chunk-EUXUH3YW.js.map +1 -0
  39. package/dist/chunk-GFVUWAG4.cjs +158 -0
  40. package/dist/chunk-GFVUWAG4.cjs.map +1 -0
  41. package/dist/chunk-IAKQFHFD.cjs +595 -0
  42. package/dist/chunk-IAKQFHFD.cjs.map +1 -0
  43. package/dist/chunk-MH7MP7XK.cjs +181 -0
  44. package/dist/chunk-MH7MP7XK.cjs.map +1 -0
  45. package/dist/chunk-NWCNJSG3.js +387 -0
  46. package/dist/chunk-NWCNJSG3.js.map +1 -0
  47. package/dist/chunk-NXU2DQAV.js +1128 -0
  48. package/dist/chunk-NXU2DQAV.js.map +1 -0
  49. package/dist/chunk-ORJK2YGG.cjs +852 -0
  50. package/dist/chunk-ORJK2YGG.cjs.map +1 -0
  51. package/dist/chunk-RFA6SEIS.cjs +1128 -0
  52. package/dist/chunk-RFA6SEIS.cjs.map +1 -0
  53. package/dist/chunk-XGIT7YUY.js +31 -0
  54. package/dist/chunk-XGIT7YUY.js.map +1 -0
  55. package/dist/chunk-XOKG3KIL.cjs +31 -0
  56. package/dist/chunk-XOKG3KIL.cjs.map +1 -0
  57. package/dist/chunk-YIWSPI4I.js +158 -0
  58. package/dist/chunk-YIWSPI4I.js.map +1 -0
  59. package/dist/chunk-ZBDE64SD.cjs +15 -0
  60. package/dist/chunk-ZBDE64SD.cjs.map +1 -0
  61. package/dist/connect-modal/index.cjs +20 -0
  62. package/dist/connect-modal/index.cjs.map +1 -0
  63. package/dist/connect-modal/index.d.cts +9 -0
  64. package/dist/connect-modal/index.d.ts +9 -0
  65. package/dist/connect-modal/index.js +20 -0
  66. package/dist/connect-modal/index.js.map +1 -0
  67. package/dist/index-D2orHGFi.d.cts +8 -0
  68. package/dist/index-D2orHGFi.d.ts +8 -0
  69. package/dist/index.cjs +793 -0
  70. package/dist/index.cjs.map +1 -0
  71. package/dist/index.d.cts +189 -0
  72. package/dist/index.d.ts +189 -0
  73. package/dist/index.js +793 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/restore-modal.cjs +9 -0
  76. package/dist/restore-modal.cjs.map +1 -0
  77. package/dist/restore-modal.d.cts +68 -0
  78. package/dist/restore-modal.d.ts +68 -0
  79. package/dist/restore-modal.js +9 -0
  80. package/dist/restore-modal.js.map +1 -0
  81. package/dist/wagmi-CVuDs_0h.d.cts +386 -0
  82. package/dist/wagmi-CVuDs_0h.d.ts +386 -0
  83. package/package.json +158 -0
  84. package/src/account-modal.ts +142 -0
  85. package/src/auto-setup.ts +362 -0
  86. package/src/avatar.ts +1135 -0
  87. package/src/backup-modal.ts +439 -0
  88. package/src/connect-modal/components/connection-view.ts +398 -0
  89. package/src/connect-modal/components/eoa-connection-view.ts +408 -0
  90. package/src/connect-modal/components/qr-code-view.ts +71 -0
  91. package/src/connect-modal/connect-modal.base.ts +18 -0
  92. package/src/connect-modal/connect-modal.config.ts +27 -0
  93. package/src/connect-modal/connect-modal.templates.ts +21 -0
  94. package/src/connect-modal/connect-modal.ts +270 -0
  95. package/src/connect-modal/connect-modal.types.ts +104 -0
  96. package/src/connect-modal/images/up-cube-glass.png +0 -0
  97. package/src/connect-modal/index.ts +23 -0
  98. package/src/connect-modal/services/wagmi.ts +266 -0
  99. package/src/connect-modal/styles/styles.css +1 -0
  100. package/src/connect-modal/utils/walletConnectDeepLinkUrl.ts +43 -0
  101. package/src/connector.ts +544 -0
  102. package/src/index.ts +62 -0
  103. package/src/popup-instance.ts +537 -0
  104. package/src/restore-modal.ts +702 -0
  105. package/src/styles/index.ts +28 -0
  106. package/src/styles/styles.css +1 -0
  107. package/src/types/css-raw.d.ts +4 -0
  108. package/src/types/images.d.ts +4 -0
  109. package/src/types.ts +168 -0
@@ -0,0 +1,852 @@
1
+ // src/avatar.ts
2
+ var DEFAULT_AVATAR_OPTIONS = {
3
+ // IconView integration options
4
+ size: "medium",
5
+ forceUnresolved: false,
6
+ // Fallback options
7
+ fallbackColor: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
8
+ fallbackText: "?",
9
+ fallbackImage: "",
10
+ // Avatar container options
11
+ avatarSize: "medium",
12
+ // Behavior options
13
+ initialPosition: "top-left",
14
+ hideThreshold: 20,
15
+ hideOffset: 30,
16
+ // Animation options
17
+ transitionDuration: "0.3s",
18
+ transitionEasing: "cubic-bezier(0.25, 0.46, 0.45, 0.94)",
19
+ // Container
20
+ container: typeof document !== "undefined" ? document.body : null
21
+ };
22
+ var DraggableAvatar = class {
23
+ constructor(options = {}) {
24
+ this.snapPreviews = /* @__PURE__ */ new Map();
25
+ // Drag state
26
+ this.isDragging = false;
27
+ this.hasDragged = false;
28
+ this.startX = 0;
29
+ this.startY = 0;
30
+ this.initialX = 0;
31
+ this.initialY = 0;
32
+ this.dragThreshold = 15;
33
+ this.isHidden = false;
34
+ this.iconViewAvailable = false;
35
+ // Animation state
36
+ this.isThrobbing = false;
37
+ this.options = { ...DEFAULT_AVATAR_OPTIONS, ...options };
38
+ if (!this.options.address && !this.options.fallbackText && !this.options.fallbackImage) {
39
+ console.warn(
40
+ "DraggableAvatar: No address, fallbackText, or fallbackImage provided. Avatar may be empty."
41
+ );
42
+ }
43
+ this.init();
44
+ }
45
+ // pixels - movement below this is still considered a click
46
+ /**
47
+ * Convert size name to pixel value
48
+ * Based on Tailwind classes: x-small=24px, small=40px, medium=56px, large=80px, x-large=96px, 2x-large=120px
49
+ */
50
+ getPixelSize(size) {
51
+ switch (size) {
52
+ case "x-small":
53
+ return 24;
54
+ case "small":
55
+ return 40;
56
+ case "medium":
57
+ return 56;
58
+ case "large":
59
+ return 80;
60
+ case "x-large":
61
+ return 96;
62
+ case "2x-large":
63
+ return 120;
64
+ }
65
+ }
66
+ /**
67
+ * Get identicon overhang for a given profile size
68
+ * The identicon hangs off the bottom-right corner by half its size
69
+ */
70
+ getIdenticonOverhang(profileSize) {
71
+ switch (profileSize) {
72
+ case "x-small":
73
+ return 6;
74
+ // w-3 = 12px, overhang = 6px
75
+ case "small":
76
+ return 8;
77
+ // w-4 = 16px, overhang = 8px
78
+ case "medium":
79
+ return 10;
80
+ // w-5 = 20px, overhang = 10px
81
+ case "large":
82
+ return 12;
83
+ // w-6 = 24px, overhang = 12px
84
+ case "x-large":
85
+ return 14;
86
+ // w-7 = 28px, overhang = 14px
87
+ case "2x-large":
88
+ return 18;
89
+ }
90
+ }
91
+ async init() {
92
+ this.createStyles();
93
+ await this.checkIconViewAvailability();
94
+ this.createElement();
95
+ this.attachEventListeners();
96
+ this.setInitialPosition();
97
+ }
98
+ /**
99
+ * Safely check for and load IconView component
100
+ */
101
+ async checkIconViewAvailability() {
102
+ if (typeof customElements !== "undefined" && customElements.get("icon-view")) {
103
+ this.iconViewAvailable = true;
104
+ return true;
105
+ }
106
+ if (this.options.address && !this.iconViewAvailable) {
107
+ try {
108
+ if (this.options.componentLoader) {
109
+ await this.options.componentLoader();
110
+ } else if (typeof window !== "undefined" && window.loadTransactionViewComponents) {
111
+ await window.loadTransactionViewComponents();
112
+ } else {
113
+ try {
114
+ await import("@lukso/transaction-view-core");
115
+ } catch (importError) {
116
+ console.warn(
117
+ "Failed to import @lukso/transaction-view-core:",
118
+ importError
119
+ );
120
+ }
121
+ }
122
+ this.iconViewAvailable = typeof customElements !== "undefined" && customElements.get("icon-view") !== void 0;
123
+ } catch (error) {
124
+ console.warn("Failed to load IconView component:", error);
125
+ this.iconViewAvailable = false;
126
+ }
127
+ }
128
+ return this.iconViewAvailable;
129
+ }
130
+ createStyles() {
131
+ if (typeof document === "undefined") return;
132
+ const avatarPixelSize = this.getPixelSize(this.options.avatarSize);
133
+ const overhang = this.getIdenticonOverhang(this.options.avatarSize);
134
+ const existingStyles = document.querySelector("#up-connector-avatar-styles");
135
+ if (existingStyles) {
136
+ existingStyles.remove();
137
+ }
138
+ const style = document.createElement("style");
139
+ style.id = "up-connector-avatar-styles";
140
+ style.textContent = `
141
+ .up-avatar-overlay {
142
+ position: fixed;
143
+ top: 0;
144
+ left: 0;
145
+ width: 100vw;
146
+ height: 100vh;
147
+ pointer-events: none;
148
+ z-index: 9999;
149
+ overflow: hidden;
150
+ }
151
+
152
+ .up-avatar {
153
+ position: absolute;
154
+ width: ${avatarPixelSize}px;
155
+ height: ${avatarPixelSize}px;
156
+ border-radius: 50%;
157
+ cursor: move;
158
+ z-index: 1000;
159
+ overflow: visible;
160
+ display: flex;
161
+ align-items: center;
162
+ justify-content: center;
163
+ user-select: none;
164
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.1);
165
+ transition: all ${this.options.transitionDuration} ${this.options.transitionEasing};
166
+ touch-action: none;
167
+ overflow: visible;
168
+ background: ${this.options.fallbackColor};
169
+ border: 3px solid rgba(255, 255, 255, 0.5) !important;
170
+ outline: none !important;
171
+ backdrop-filter: blur(10px);
172
+ pointer-events: auto;
173
+ }
174
+
175
+ .up-avatar * {
176
+ user-select: none !important;
177
+ pointer-events: none !important;
178
+ }
179
+
180
+ .up-avatar img {
181
+ draggable: false !important;
182
+ }
183
+
184
+ .up-avatar:hover {
185
+ transform: scale(1.05);
186
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25), 0 4px 12px rgba(0, 0, 0, 0.15);
187
+ }
188
+
189
+ .up-avatar:focus {
190
+ outline: none !important;
191
+ border: 3px solid rgba(255, 255, 255, 0.6) !important;
192
+ }
193
+
194
+ .up-avatar.dragging {
195
+ transform: scale(1.1);
196
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3), 0 6px 16px rgba(0, 0, 0, 0.2);
197
+ cursor: grabbing;
198
+ }
199
+
200
+ .up-avatar.hidden-left {
201
+ left: -${this.options.hideOffset}px !important;
202
+ opacity: 0.8;
203
+ }
204
+
205
+ .up-avatar.hidden-right {
206
+ right: -${this.options.hideOffset}px !important;
207
+ left: auto !important;
208
+ opacity: 0.8;
209
+ }
210
+
211
+ .up-avatar.hidden-left:hover,
212
+ .up-avatar.hidden-right:hover {
213
+ transform: translateX(0) scale(1.05);
214
+ opacity: 1;
215
+ }
216
+
217
+ .up-avatar.hidden-left:hover {
218
+ left: -12px !important;
219
+ }
220
+
221
+ .up-avatar.hidden-right:hover {
222
+ right: -12px !important;
223
+ }
224
+
225
+ /* IconView positioned to allow identicon to extend beyond border */
226
+ .up-avatar icon-view {
227
+ position: absolute !important;
228
+ top: 0 !important;
229
+ left: 0 !important;
230
+ width: ${avatarPixelSize}px !important;
231
+ height: ${avatarPixelSize}px !important;
232
+ display: block !important;
233
+ z-index: 1 !important;
234
+ }
235
+
236
+ /* Additional auto-sizing for IconView components */
237
+ .up-avatar icon-view * {
238
+ max-width: ${avatarPixelSize}px !important;
239
+ max-height: ${avatarPixelSize}px !important;
240
+ }
241
+
242
+ /* Let IconView handle its own internal sizing */
243
+
244
+ .up-avatar icon-view img,
245
+ .up-avatar icon-view .icon,
246
+ .up-avatar icon-view .profile-image {
247
+ max-width: 100% !important;
248
+ max-height: 100% !important;
249
+ width: auto !important;
250
+ height: auto !important;
251
+ object-fit: cover;
252
+ draggable: false !important;
253
+ user-select: none !important;
254
+ pointer-events: none !important;
255
+ }
256
+
257
+ /* Fallback content */
258
+ .up-avatar .fallback-content {
259
+ width: 100%;
260
+ height: 100%;
261
+ display: flex;
262
+ align-items: center;
263
+ justify-content: center;
264
+ color: white;
265
+ font-weight: 600;
266
+ font-size: ${Math.floor(avatarPixelSize * 0.4)}px;
267
+ font-family: system-ui, -apple-system, sans-serif;
268
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
269
+ }
270
+
271
+ .up-avatar .fallback-content img {
272
+ width: 100%;
273
+ height: 100%;
274
+ border-radius: 50%;
275
+ object-fit: cover;
276
+ draggable: false !important;
277
+ user-select: none !important;
278
+ pointer-events: none !important;
279
+ }
280
+
281
+ /* Snap preview */
282
+ .up-avatar-preview {
283
+ position: absolute;
284
+ width: ${avatarPixelSize}px;
285
+ height: ${avatarPixelSize}px;
286
+ border-radius: 50%;
287
+ z-index: 999;
288
+ pointer-events: none;
289
+ background: rgba(102, 126, 234, 0.1);
290
+ backdrop-filter: blur(5px);
291
+ box-shadow:
292
+ 0 0 0 2px rgba(255, 255, 255, 0.3),
293
+ 0 0 0 4px rgba(102, 126, 234, 0.3),
294
+ 0 2px 8px rgba(0, 0, 0, 0.2);
295
+ opacity: 0.5;
296
+ transition: opacity 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
297
+ }
298
+
299
+ .up-avatar-preview.active {
300
+ background: rgba(102, 126, 234, 0.2);
301
+ box-shadow:
302
+ 0 0 0 2px white,
303
+ 0 0 0 4px #667eea,
304
+ 0 4px 12px rgba(0, 0, 0, 0.3);
305
+ opacity: 1;
306
+ }
307
+
308
+ /* Hide IconView labels in avatar mode */
309
+ .up-avatar icon-view .label {
310
+ display: none;
311
+ }
312
+
313
+ /* Connection indicator */
314
+ .up-avatar::after {
315
+ content: '';
316
+ position: absolute;
317
+ bottom: 2px;
318
+ right: 2px;
319
+ width: 16px;
320
+ height: 16px;
321
+ border-radius: 50%;
322
+ background: #4ade80;
323
+ border: 2px solid white;
324
+ opacity: 0;
325
+ transform: scale(0);
326
+ transition: all 0.2s ease;
327
+ }
328
+
329
+ .up-avatar.connected::after {
330
+ opacity: 1;
331
+ transform: scale(1);
332
+ }
333
+
334
+ /* Throb animation for transactions */
335
+ .up-avatar.throbbing {
336
+ animation: avatar-throb 2s ease-in-out infinite;
337
+ }
338
+
339
+ @keyframes avatar-throb {
340
+ 0%, 100% {
341
+ transform: scale(1);
342
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
343
+ border-color: rgba(255, 255, 255, 0.1);
344
+ }
345
+ 50% {
346
+ transform: scale(1.1);
347
+ box-shadow:
348
+ 0 8px 24px rgba(0, 0, 0, 0.3),
349
+ 0 0 0 4px rgba(102, 126, 234, 0.4),
350
+ 0 0 0 8px rgba(102, 126, 234, 0.2),
351
+ 0 0 20px rgba(102, 126, 234, 0.3);
352
+ border-color: rgba(102, 126, 234, 0.8);
353
+ }
354
+ }
355
+
356
+ .up-avatar.throbbing::before {
357
+ content: '';
358
+ position: absolute;
359
+ top: -4px;
360
+ left: -4px;
361
+ right: -4px;
362
+ bottom: -4px;
363
+ border: 2px solid transparent;
364
+ border-radius: 50%;
365
+ background: conic-gradient(from 0deg, transparent, #667eea, #764ba2, transparent);
366
+ background-size: 200% 200%;
367
+ animation: avatar-rotate 1.5s linear infinite;
368
+ z-index: -1;
369
+ }
370
+
371
+ @keyframes avatar-rotate {
372
+ 0% { transform: rotate(0deg); }
373
+ 100% { transform: rotate(360deg); }
374
+ }
375
+ `;
376
+ document.head.appendChild(style);
377
+ }
378
+ createElement() {
379
+ if (typeof document === "undefined") return;
380
+ this.overlay = document.createElement("div");
381
+ this.overlay.className = "up-avatar-overlay";
382
+ this.element = document.createElement("div");
383
+ this.element.className = "up-avatar";
384
+ this.element.setAttribute("role", "button");
385
+ this.element.setAttribute("tabindex", "0");
386
+ this.element.setAttribute("aria-label", "Universal Profile avatar");
387
+ this.createContent();
388
+ this.overlay.appendChild(this.element);
389
+ this.options.container.appendChild(this.overlay);
390
+ }
391
+ createContent() {
392
+ if (!this.element) return;
393
+ this.element.innerHTML = "";
394
+ if (this.options.address && this.iconViewAvailable) {
395
+ this.iconViewElement = document.createElement("icon-view");
396
+ this.iconViewElement.setAttribute("address", this.options.address);
397
+ if (this.options.chainId) {
398
+ this.iconViewElement.setAttribute(
399
+ "chain-id",
400
+ this.options.chainId.toString()
401
+ );
402
+ }
403
+ if (this.options.resolved) {
404
+ ;
405
+ this.iconViewElement.resolved = this.options.resolved;
406
+ }
407
+ this.iconViewElement.setAttribute("size", this.options.avatarSize);
408
+ if (this.options.label) {
409
+ this.iconViewElement.setAttribute("label", this.options.label);
410
+ }
411
+ if (this.options.forceUnresolved) {
412
+ this.iconViewElement.setAttribute("force-unresolved", "");
413
+ }
414
+ this.iconViewElement.addEventListener("address-click", (event) => {
415
+ event.stopPropagation();
416
+ if (this.options.onAddressClick) {
417
+ this.options.onAddressClick(event);
418
+ }
419
+ });
420
+ this.element.appendChild(this.iconViewElement);
421
+ } else {
422
+ this.createFallbackContent();
423
+ }
424
+ }
425
+ createFallbackContent() {
426
+ if (!this.element) return;
427
+ const fallbackDiv = document.createElement("div");
428
+ fallbackDiv.className = "fallback-content";
429
+ if (this.options.fallbackImage) {
430
+ const img = document.createElement("img");
431
+ img.src = this.options.fallbackImage;
432
+ img.alt = "Avatar";
433
+ img.onerror = () => {
434
+ img.remove();
435
+ fallbackDiv.textContent = this.options.fallbackText;
436
+ };
437
+ fallbackDiv.appendChild(img);
438
+ } else {
439
+ fallbackDiv.textContent = this.options.fallbackText;
440
+ }
441
+ this.element.appendChild(fallbackDiv);
442
+ }
443
+ attachEventListeners() {
444
+ if (!this.element) return;
445
+ this.element.addEventListener("mousedown", this.handleMouseDown.bind(this));
446
+ document.addEventListener("mousemove", this.handleMouseMove.bind(this));
447
+ document.addEventListener("mouseup", this.handleMouseUp.bind(this));
448
+ this.element.addEventListener(
449
+ "touchstart",
450
+ this.handleTouchStart.bind(this),
451
+ { passive: false }
452
+ );
453
+ document.addEventListener("touchmove", this.handleTouchMove.bind(this), {
454
+ passive: false
455
+ });
456
+ document.addEventListener("touchend", this.handleTouchEnd.bind(this), {
457
+ passive: false
458
+ });
459
+ this.element.addEventListener("click", this.handleClick.bind(this));
460
+ window.addEventListener("resize", this.handleResize.bind(this));
461
+ }
462
+ getSnapPositions() {
463
+ const margin = 20;
464
+ const size = this.getPixelSize(this.options.avatarSize);
465
+ const positions = [
466
+ { x: margin, y: margin, side: "left", name: "top-left" },
467
+ {
468
+ x: window.innerWidth - size - margin,
469
+ y: margin,
470
+ side: "right",
471
+ name: "top-right"
472
+ },
473
+ {
474
+ x: margin,
475
+ y: window.innerHeight - size - margin,
476
+ side: "left",
477
+ name: "bottom-left"
478
+ },
479
+ {
480
+ x: window.innerWidth - size - margin,
481
+ y: window.innerHeight - size - margin,
482
+ side: "right",
483
+ name: "bottom-right"
484
+ }
485
+ ];
486
+ return positions;
487
+ }
488
+ findClosestSnapPosition(x, y) {
489
+ const positions = this.getSnapPositions();
490
+ let closest = positions[0];
491
+ let minDistance = Infinity;
492
+ positions.forEach((pos) => {
493
+ const distance = Math.sqrt(
494
+ Math.pow(x - pos.x, 2) + Math.pow(y - pos.y, 2)
495
+ );
496
+ if (distance < minDistance) {
497
+ minDistance = distance;
498
+ closest = pos;
499
+ }
500
+ });
501
+ return closest;
502
+ }
503
+ setInitialPosition() {
504
+ const positions = this.getSnapPositions();
505
+ const initialPos = positions.find((p) => p.name === this.options.initialPosition) || positions[0];
506
+ this.snapToPosition(initialPos);
507
+ }
508
+ snapToPosition(position, shouldHide = false) {
509
+ if (!this.element) return;
510
+ this.element.className = "up-avatar";
511
+ this.currentPosition = position;
512
+ this.isHidden = shouldHide;
513
+ if (shouldHide) {
514
+ if (position.side === "left") {
515
+ this.element.classList.add("hidden-left");
516
+ this.element.style.left = `-${this.options.hideOffset}px`;
517
+ this.element.style.right = "auto";
518
+ this.element.style.top = position.y + "px";
519
+ this.options.onHide?.();
520
+ } else if (position.side === "right") {
521
+ this.element.classList.add("hidden-right");
522
+ this.element.style.right = `-${this.options.hideOffset}px`;
523
+ this.element.style.left = "auto";
524
+ this.element.style.top = position.y + "px";
525
+ this.options.onHide?.();
526
+ }
527
+ } else {
528
+ this.element.style.left = position.x + "px";
529
+ this.element.style.right = "auto";
530
+ this.element.style.top = position.y + "px";
531
+ if (this.isHidden) {
532
+ this.options.onShow?.();
533
+ }
534
+ }
535
+ this.options.onPositionChange?.(position.name);
536
+ }
537
+ showAllSnapPreviews() {
538
+ if (typeof document === "undefined") return;
539
+ const positions = this.getSnapPositions();
540
+ positions.forEach((pos) => {
541
+ if (!this.snapPreviews.has(pos.name)) {
542
+ const preview = document.createElement("div");
543
+ preview.className = "up-avatar-preview";
544
+ preview.style.left = pos.x + "px";
545
+ preview.style.top = pos.y + "px";
546
+ this.overlay.appendChild(preview);
547
+ this.snapPreviews.set(pos.name, preview);
548
+ }
549
+ });
550
+ }
551
+ updateActiveSnapPreview(activePosition, shouldHide = false) {
552
+ if (typeof document === "undefined") return;
553
+ let activeKey = activePosition.name;
554
+ this.snapPreviews.forEach((preview, key) => {
555
+ if (key === activeKey) {
556
+ preview.classList.add("active");
557
+ if (shouldHide) {
558
+ if (activePosition.side === "left") {
559
+ preview.style.left = `-${this.options.hideOffset}px`;
560
+ preview.style.right = "auto";
561
+ preview.style.top = activePosition.y + "px";
562
+ } else if (activePosition.side === "right") {
563
+ preview.style.right = `-${this.options.hideOffset}px`;
564
+ preview.style.left = "auto";
565
+ preview.style.top = activePosition.y + "px";
566
+ }
567
+ } else {
568
+ preview.style.left = activePosition.x + "px";
569
+ preview.style.right = "auto";
570
+ preview.style.top = activePosition.y + "px";
571
+ }
572
+ } else {
573
+ preview.classList.remove("active");
574
+ const pos = this.getSnapPositions().find((p) => p.name === key);
575
+ if (pos) {
576
+ preview.style.left = pos.x + "px";
577
+ preview.style.right = "auto";
578
+ preview.style.top = pos.y + "px";
579
+ }
580
+ }
581
+ });
582
+ }
583
+ hideAllSnapPreviews() {
584
+ this.snapPreviews.forEach((preview) => {
585
+ preview.remove();
586
+ });
587
+ this.snapPreviews.clear();
588
+ }
589
+ // Event handlers
590
+ handleMouseDown(e) {
591
+ if (e.button !== 0) {
592
+ return;
593
+ }
594
+ this.isDragging = true;
595
+ this.hasDragged = false;
596
+ this.startX = e.clientX;
597
+ this.startY = e.clientY;
598
+ const rect = this.element.getBoundingClientRect();
599
+ this.initialX = rect.left;
600
+ this.initialY = rect.top;
601
+ this.element.classList.add("dragging");
602
+ this.element.style.transition = "none";
603
+ this.showAllSnapPreviews();
604
+ }
605
+ handleMouseMove(e) {
606
+ if (!this.isDragging) return;
607
+ e.preventDefault();
608
+ const currentX = this.initialX + (e.clientX - this.startX);
609
+ const currentY = this.initialY + (e.clientY - this.startY);
610
+ const deltaX = Math.abs(e.clientX - this.startX);
611
+ const deltaY = Math.abs(e.clientY - this.startY);
612
+ const totalMovement = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
613
+ if (totalMovement > this.dragThreshold) {
614
+ this.hasDragged = true;
615
+ }
616
+ this.element.className = "up-avatar dragging";
617
+ this.element.style.left = currentX + "px";
618
+ this.element.style.right = "auto";
619
+ this.element.style.top = currentY + "px";
620
+ const closestPosition = this.findClosestSnapPosition(currentX, currentY);
621
+ const shouldHideLeft = currentX < -this.options.hideThreshold;
622
+ const shouldHideRight = currentX > window.innerWidth - this.getPixelSize(this.options.avatarSize) + this.options.hideThreshold;
623
+ this.updateActiveSnapPreview(
624
+ closestPosition,
625
+ shouldHideLeft || shouldHideRight
626
+ );
627
+ }
628
+ handleMouseUp() {
629
+ if (this.isDragging) {
630
+ this.isDragging = false;
631
+ this.element.classList.remove("dragging");
632
+ this.element.style.transition = `all ${this.options.transitionDuration} ${this.options.transitionEasing}`;
633
+ this.hideAllSnapPreviews();
634
+ const rect = this.element.getBoundingClientRect();
635
+ const currentX = rect.left;
636
+ const currentY = rect.top;
637
+ const shouldHideLeft = currentX < -this.options.hideThreshold;
638
+ const shouldHideRight = currentX > window.innerWidth - this.getPixelSize(this.options.avatarSize) + this.options.hideThreshold;
639
+ const closestPosition = this.findClosestSnapPosition(currentX, currentY);
640
+ this.snapToPosition(closestPosition, shouldHideLeft || shouldHideRight);
641
+ setTimeout(() => {
642
+ this.hasDragged = false;
643
+ }, 0);
644
+ }
645
+ }
646
+ handleTouchStart(e) {
647
+ e.preventDefault();
648
+ e.stopPropagation();
649
+ this.isDragging = true;
650
+ this.hasDragged = false;
651
+ const touch = e.touches[0];
652
+ this.startX = touch.clientX;
653
+ this.startY = touch.clientY;
654
+ const rect = this.element.getBoundingClientRect();
655
+ this.initialX = rect.left;
656
+ this.initialY = rect.top;
657
+ this.element.classList.add("dragging");
658
+ this.element.style.transition = "none";
659
+ this.showAllSnapPreviews();
660
+ }
661
+ handleTouchMove(e) {
662
+ if (!this.isDragging) return;
663
+ e.preventDefault();
664
+ e.stopPropagation();
665
+ const touch = e.touches[0];
666
+ const currentX = this.initialX + (touch.clientX - this.startX);
667
+ const currentY = this.initialY + (touch.clientY - this.startY);
668
+ const deltaX = Math.abs(touch.clientX - this.startX);
669
+ const deltaY = Math.abs(touch.clientY - this.startY);
670
+ const totalMovement = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
671
+ if (totalMovement > this.dragThreshold) {
672
+ this.hasDragged = true;
673
+ }
674
+ this.element.className = "up-avatar dragging";
675
+ this.element.style.left = currentX + "px";
676
+ this.element.style.right = "auto";
677
+ this.element.style.top = currentY + "px";
678
+ const closestPosition = this.findClosestSnapPosition(currentX, currentY);
679
+ const shouldHideLeft = currentX < -this.options.hideThreshold;
680
+ const shouldHideRight = currentX > window.innerWidth - this.getPixelSize(this.options.avatarSize) + this.options.hideThreshold;
681
+ this.updateActiveSnapPreview(
682
+ closestPosition,
683
+ shouldHideLeft || shouldHideRight
684
+ );
685
+ }
686
+ handleTouchEnd(e) {
687
+ if (this.isDragging) {
688
+ e.preventDefault();
689
+ e.stopPropagation();
690
+ this.isDragging = false;
691
+ this.element.classList.remove("dragging");
692
+ this.element.style.transition = `all ${this.options.transitionDuration} ${this.options.transitionEasing}`;
693
+ this.hideAllSnapPreviews();
694
+ const rect = this.element.getBoundingClientRect();
695
+ const currentX = rect.left;
696
+ const currentY = rect.top;
697
+ const shouldHideLeft = currentX < -this.options.hideThreshold;
698
+ const shouldHideRight = currentX > window.innerWidth - this.getPixelSize(this.options.avatarSize) + this.options.hideThreshold;
699
+ const closestPosition = this.findClosestSnapPosition(currentX, currentY);
700
+ this.snapToPosition(closestPosition, shouldHideLeft || shouldHideRight);
701
+ setTimeout(() => {
702
+ this.hasDragged = false;
703
+ }, 0);
704
+ }
705
+ }
706
+ handleClick(e) {
707
+ if (e.button !== 0) {
708
+ return;
709
+ }
710
+ if (!this.hasDragged) {
711
+ if (this.options.onClick) {
712
+ const resolvedData = this.iconViewElement?.resolved || null;
713
+ this.options.onClick(e, {
714
+ address: this.options.address,
715
+ resolved: resolvedData
716
+ });
717
+ }
718
+ }
719
+ }
720
+ handleResize() {
721
+ if (this.currentPosition) {
722
+ const positions = this.getSnapPositions();
723
+ const newPosition = positions.find((p) => p.name === this.currentPosition.name) || positions[0];
724
+ this.snapToPosition(newPosition, this.isHidden);
725
+ }
726
+ }
727
+ // Public API methods
728
+ setPosition(positionName) {
729
+ const positions = this.getSnapPositions();
730
+ const position = positions.find((p) => p.name === positionName);
731
+ if (position) {
732
+ this.snapToPosition(position);
733
+ }
734
+ }
735
+ hide() {
736
+ if (this.currentPosition) {
737
+ this.snapToPosition(this.currentPosition, true);
738
+ }
739
+ }
740
+ show() {
741
+ if (this.currentPosition) {
742
+ this.snapToPosition(this.currentPosition, false);
743
+ }
744
+ }
745
+ setConnected(connected) {
746
+ if (this.element) {
747
+ if (connected) {
748
+ this.element.classList.add("connected");
749
+ } else {
750
+ this.element.classList.remove("connected");
751
+ }
752
+ }
753
+ }
754
+ updateAddress(address, resolved, chainId) {
755
+ this.options.address = address;
756
+ this.options.resolved = resolved;
757
+ this.options.chainId = chainId;
758
+ if (this.iconViewElement) {
759
+ this.iconViewElement.setAttribute("address", address);
760
+ if (chainId) {
761
+ this.iconViewElement.setAttribute("chain-id", chainId.toString());
762
+ }
763
+ if (resolved) {
764
+ ;
765
+ this.iconViewElement.resolved = resolved;
766
+ }
767
+ } else {
768
+ this.createContent();
769
+ }
770
+ }
771
+ updateResolved(resolved) {
772
+ this.options.resolved = resolved;
773
+ if (this.iconViewElement) {
774
+ ;
775
+ this.iconViewElement.resolved = resolved;
776
+ }
777
+ }
778
+ updateSize(newSize) {
779
+ if (this.options.avatarSize === newSize) return;
780
+ this.options.avatarSize = newSize;
781
+ this.createStyles();
782
+ const pixelSize = this.getPixelSize(newSize);
783
+ if (this.element) {
784
+ this.element.style.width = `${pixelSize}px`;
785
+ this.element.style.height = `${pixelSize}px`;
786
+ }
787
+ if (this.iconViewElement) {
788
+ this.iconViewElement.setAttribute("size", newSize);
789
+ const iconView = this.iconViewElement;
790
+ if (iconView.requestUpdate) {
791
+ iconView.requestUpdate();
792
+ }
793
+ this.iconViewElement.style.width = "";
794
+ this.iconViewElement.style.height = "";
795
+ const profiles = this.iconViewElement.querySelectorAll("lukso-profile");
796
+ profiles.forEach((profile) => {
797
+ const element = profile;
798
+ element.style.width = "";
799
+ element.style.height = "";
800
+ element.setAttribute("size", newSize);
801
+ });
802
+ }
803
+ this.createContent();
804
+ }
805
+ getElement() {
806
+ return this.element || null;
807
+ }
808
+ getPosition() {
809
+ if (!this.element || !this.currentPosition) return null;
810
+ const rect = this.element.getBoundingClientRect();
811
+ return {
812
+ x: rect.left,
813
+ y: rect.top,
814
+ name: this.currentPosition.name
815
+ };
816
+ }
817
+ startThrob() {
818
+ if (!this.element || this.isThrobbing) return;
819
+ this.isThrobbing = true;
820
+ this.element.classList.add("throbbing");
821
+ }
822
+ stopThrob() {
823
+ if (!this.element || !this.isThrobbing) return;
824
+ this.isThrobbing = false;
825
+ this.element.classList.remove("throbbing");
826
+ }
827
+ getAvatarRect() {
828
+ return this.element ? this.element.getBoundingClientRect() : null;
829
+ }
830
+ destroy() {
831
+ this.stopThrob();
832
+ if (this.overlay) {
833
+ this.overlay.remove();
834
+ }
835
+ if (typeof document !== "undefined" && !document.querySelector(".up-avatar-overlay")) {
836
+ const styles = document.querySelector("#up-connector-avatar-styles");
837
+ styles?.remove();
838
+ }
839
+ }
840
+ };
841
+ async function createAvatar(options = {}) {
842
+ const avatar = new DraggableAvatar(options);
843
+ return avatar;
844
+ }
845
+ var avatar_default = DraggableAvatar;
846
+
847
+ export {
848
+ DraggableAvatar,
849
+ createAvatar,
850
+ avatar_default
851
+ };
852
+ //# sourceMappingURL=chunk-6N35TCFT.js.map