@weldsuite/helpdesk-widget-sdk 1.0.14 → 1.0.16
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.
- package/dist/angular.d.ts +4 -0
- package/dist/angular.esm.js +248 -50
- package/dist/angular.esm.js.map +1 -1
- package/dist/angular.js +248 -50
- package/dist/angular.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.esm.js +248 -50
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +248 -50
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +248 -50
- package/dist/index.umd.js.map +1 -1
- package/dist/react.d.ts +4 -0
- package/dist/react.esm.js +248 -50
- package/dist/react.esm.js.map +1 -1
- package/dist/react.js +248 -50
- package/dist/react.js.map +1 -1
- package/dist/vue-composables.esm.js +248 -50
- package/dist/vue-composables.esm.js.map +1 -1
- package/dist/vue-composables.js +248 -50
- package/dist/vue-composables.js.map +1 -1
- package/package.json +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -514,14 +514,16 @@
|
|
|
514
514
|
const container = document.createElement('div');
|
|
515
515
|
container.className = 'weld-launcher-frame';
|
|
516
516
|
container.setAttribute('data-state', 'visible');
|
|
517
|
+
// Container is larger than the button to allow hover animations (scale, shadow) without clipping
|
|
518
|
+
const launcherPadding = 10;
|
|
517
519
|
container.style.cssText = `
|
|
518
520
|
position: fixed;
|
|
519
|
-
bottom: ${launcher.position.bottom};
|
|
520
|
-
right: ${launcher.position.right};
|
|
521
|
-
width: ${launcher.size};
|
|
522
|
-
height: ${launcher.size};
|
|
521
|
+
bottom: calc(${launcher.position.bottom} - ${launcherPadding}px);
|
|
522
|
+
right: calc(${launcher.position.right} - ${launcherPadding}px);
|
|
523
|
+
width: calc(${launcher.size} + ${launcherPadding * 2}px);
|
|
524
|
+
height: calc(${launcher.size} + ${launcherPadding * 2}px);
|
|
523
525
|
z-index: 2147483003;
|
|
524
|
-
pointer-events:
|
|
526
|
+
pointer-events: none;
|
|
525
527
|
display: block;
|
|
526
528
|
`;
|
|
527
529
|
// Create iframe
|
|
@@ -535,6 +537,7 @@
|
|
|
535
537
|
border: none;
|
|
536
538
|
background: transparent;
|
|
537
539
|
display: block;
|
|
540
|
+
pointer-events: auto;
|
|
538
541
|
`;
|
|
539
542
|
iframe.setAttribute('allow', 'clipboard-write');
|
|
540
543
|
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');
|
|
@@ -655,43 +658,10 @@
|
|
|
655
658
|
this.logger.debug('Widget iframe created');
|
|
656
659
|
}
|
|
657
660
|
/**
|
|
658
|
-
* Create backdrop iframe
|
|
661
|
+
* Create backdrop iframe — disabled, widget stays non-modal so users can interact with the page
|
|
659
662
|
*/
|
|
660
663
|
async createBackdropIframe() {
|
|
661
|
-
|
|
662
|
-
this.logger.debug('Backdrop disabled, skipping creation');
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
// Create container
|
|
666
|
-
const container = document.createElement('div');
|
|
667
|
-
container.className = 'weld-backdrop-frame';
|
|
668
|
-
container.setAttribute('data-state', 'hidden');
|
|
669
|
-
container.style.cssText = `
|
|
670
|
-
position: fixed;
|
|
671
|
-
top: 0;
|
|
672
|
-
left: 0;
|
|
673
|
-
right: 0;
|
|
674
|
-
bottom: 0;
|
|
675
|
-
z-index: 2147483000;
|
|
676
|
-
background: transparent;
|
|
677
|
-
pointer-events: none;
|
|
678
|
-
opacity: 0;
|
|
679
|
-
transition: opacity 200ms ease;
|
|
680
|
-
`;
|
|
681
|
-
this.appContainer?.appendChild(container);
|
|
682
|
-
// Store metadata (backdrop doesn't have an iframe, just a div)
|
|
683
|
-
// We'll create a minimal "iframe" reference for consistency
|
|
684
|
-
const dummyIframe = document.createElement('iframe');
|
|
685
|
-
dummyIframe.style.display = 'none';
|
|
686
|
-
this.iframes.set(exports.IframeType.BACKDROP, {
|
|
687
|
-
type: exports.IframeType.BACKDROP,
|
|
688
|
-
element: dummyIframe,
|
|
689
|
-
container,
|
|
690
|
-
ready: true, // Backdrop is always ready
|
|
691
|
-
visible: false,
|
|
692
|
-
createdAt: Date.now(),
|
|
693
|
-
});
|
|
694
|
-
this.logger.debug('Backdrop created');
|
|
664
|
+
this.logger.debug('Backdrop disabled, skipping creation');
|
|
695
665
|
}
|
|
696
666
|
/**
|
|
697
667
|
* Build iframe URL with parameters
|
|
@@ -1029,11 +999,7 @@
|
|
|
1029
999
|
* Validate message origin
|
|
1030
1000
|
*/
|
|
1031
1001
|
isOriginAllowed(origin) {
|
|
1032
|
-
//
|
|
1033
|
-
if (this.config.allowedOrigins?.length === 0) {
|
|
1034
|
-
return origin === window.location.origin;
|
|
1035
|
-
}
|
|
1036
|
-
// Check if origin is in allowed list
|
|
1002
|
+
// Check if origin is in allowed list (includes same-origin and programmatically added origins)
|
|
1037
1003
|
if (this.allowedOrigins.has(origin)) {
|
|
1038
1004
|
return true;
|
|
1039
1005
|
}
|
|
@@ -2405,7 +2371,7 @@
|
|
|
2405
2371
|
}
|
|
2406
2372
|
}
|
|
2407
2373
|
|
|
2408
|
-
var version = "1.0.
|
|
2374
|
+
var version = "1.0.16";
|
|
2409
2375
|
var packageJson = {
|
|
2410
2376
|
version: version};
|
|
2411
2377
|
|
|
@@ -2488,6 +2454,242 @@
|
|
|
2488
2454
|
console.log('[Weld SDK] Widget close requested');
|
|
2489
2455
|
this.close();
|
|
2490
2456
|
}
|
|
2457
|
+
if (event.data?.type === 'weld:image:open' && event.data?.url) {
|
|
2458
|
+
this.showImageLightbox(event.data.url);
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* Show fullscreen image lightbox on the parent page
|
|
2463
|
+
*/
|
|
2464
|
+
showImageLightbox(url) {
|
|
2465
|
+
// Remove existing lightbox if any
|
|
2466
|
+
const existing = document.getElementById('weld-image-lightbox');
|
|
2467
|
+
if (existing)
|
|
2468
|
+
existing.remove();
|
|
2469
|
+
// Zoom / pan state
|
|
2470
|
+
let scale = 1;
|
|
2471
|
+
let translateX = 0;
|
|
2472
|
+
let translateY = 0;
|
|
2473
|
+
let isDragging = false;
|
|
2474
|
+
let dragStartX = 0;
|
|
2475
|
+
let dragStartY = 0;
|
|
2476
|
+
let lastTranslateX = 0;
|
|
2477
|
+
let lastTranslateY = 0;
|
|
2478
|
+
const applyTransform = () => {
|
|
2479
|
+
img.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
|
|
2480
|
+
};
|
|
2481
|
+
const resetTransform = () => {
|
|
2482
|
+
scale = 1;
|
|
2483
|
+
translateX = 0;
|
|
2484
|
+
translateY = 0;
|
|
2485
|
+
applyTransform();
|
|
2486
|
+
img.style.cursor = 'zoom-in';
|
|
2487
|
+
};
|
|
2488
|
+
const overlay = document.createElement('div');
|
|
2489
|
+
overlay.id = 'weld-image-lightbox';
|
|
2490
|
+
overlay.style.cssText = `
|
|
2491
|
+
position: fixed;
|
|
2492
|
+
inset: 0;
|
|
2493
|
+
z-index: 2147483647;
|
|
2494
|
+
background: rgba(0, 0, 0, 0.92);
|
|
2495
|
+
display: flex;
|
|
2496
|
+
align-items: center;
|
|
2497
|
+
justify-content: center;
|
|
2498
|
+
padding: 16px;
|
|
2499
|
+
cursor: pointer;
|
|
2500
|
+
overflow: hidden;
|
|
2501
|
+
`;
|
|
2502
|
+
// Close button
|
|
2503
|
+
const closeBtn = document.createElement('button');
|
|
2504
|
+
closeBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`;
|
|
2505
|
+
closeBtn.style.cssText = `
|
|
2506
|
+
position: absolute;
|
|
2507
|
+
top: 16px;
|
|
2508
|
+
right: 16px;
|
|
2509
|
+
width: 40px;
|
|
2510
|
+
height: 40px;
|
|
2511
|
+
border-radius: 50%;
|
|
2512
|
+
border: none;
|
|
2513
|
+
background: rgba(255, 255, 255, 0.1);
|
|
2514
|
+
color: white;
|
|
2515
|
+
cursor: pointer;
|
|
2516
|
+
display: flex;
|
|
2517
|
+
align-items: center;
|
|
2518
|
+
justify-content: center;
|
|
2519
|
+
transition: background 0.15s;
|
|
2520
|
+
`;
|
|
2521
|
+
closeBtn.onmouseenter = () => { closeBtn.style.background = 'rgba(255, 255, 255, 0.2)'; };
|
|
2522
|
+
closeBtn.onmouseleave = () => { closeBtn.style.background = 'rgba(255, 255, 255, 0.1)'; };
|
|
2523
|
+
// Download button
|
|
2524
|
+
const downloadBtn = document.createElement('a');
|
|
2525
|
+
downloadBtn.href = url;
|
|
2526
|
+
downloadBtn.download = '';
|
|
2527
|
+
downloadBtn.target = '_blank';
|
|
2528
|
+
downloadBtn.rel = 'noopener noreferrer';
|
|
2529
|
+
downloadBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>`;
|
|
2530
|
+
downloadBtn.style.cssText = `
|
|
2531
|
+
position: absolute;
|
|
2532
|
+
top: 16px;
|
|
2533
|
+
right: 64px;
|
|
2534
|
+
width: 40px;
|
|
2535
|
+
height: 40px;
|
|
2536
|
+
border-radius: 50%;
|
|
2537
|
+
border: none;
|
|
2538
|
+
background: rgba(255, 255, 255, 0.1);
|
|
2539
|
+
color: white;
|
|
2540
|
+
cursor: pointer;
|
|
2541
|
+
display: flex;
|
|
2542
|
+
align-items: center;
|
|
2543
|
+
justify-content: center;
|
|
2544
|
+
transition: background 0.15s;
|
|
2545
|
+
text-decoration: none;
|
|
2546
|
+
`;
|
|
2547
|
+
downloadBtn.onmouseenter = () => { downloadBtn.style.background = 'rgba(255, 255, 255, 0.2)'; };
|
|
2548
|
+
downloadBtn.onmouseleave = () => { downloadBtn.style.background = 'rgba(255, 255, 255, 0.1)'; };
|
|
2549
|
+
// Image
|
|
2550
|
+
const img = document.createElement('img');
|
|
2551
|
+
img.src = url;
|
|
2552
|
+
img.alt = 'Full size';
|
|
2553
|
+
img.draggable = false;
|
|
2554
|
+
img.style.cssText = `
|
|
2555
|
+
max-width: 100%;
|
|
2556
|
+
max-height: 100%;
|
|
2557
|
+
object-fit: contain;
|
|
2558
|
+
border-radius: 8px;
|
|
2559
|
+
cursor: zoom-in;
|
|
2560
|
+
transition: transform 0.2s ease;
|
|
2561
|
+
user-select: none;
|
|
2562
|
+
`;
|
|
2563
|
+
// Click to toggle zoom
|
|
2564
|
+
img.addEventListener('click', (e) => {
|
|
2565
|
+
e.stopPropagation();
|
|
2566
|
+
if (scale === 1) {
|
|
2567
|
+
// Zoom in to 2.5x centered on click position
|
|
2568
|
+
const rect = img.getBoundingClientRect();
|
|
2569
|
+
const clickX = e.clientX - rect.left - rect.width / 2;
|
|
2570
|
+
const clickY = e.clientY - rect.top - rect.height / 2;
|
|
2571
|
+
scale = 2.5;
|
|
2572
|
+
translateX = -clickX * 1.5;
|
|
2573
|
+
translateY = -clickY * 1.5;
|
|
2574
|
+
applyTransform();
|
|
2575
|
+
img.style.cursor = 'zoom-out';
|
|
2576
|
+
}
|
|
2577
|
+
else {
|
|
2578
|
+
// Zoom out - reset
|
|
2579
|
+
resetTransform();
|
|
2580
|
+
}
|
|
2581
|
+
});
|
|
2582
|
+
// Mouse wheel zoom
|
|
2583
|
+
overlay.addEventListener('wheel', (e) => {
|
|
2584
|
+
e.preventDefault();
|
|
2585
|
+
const delta = e.deltaY > 0 ? -0.25 : 0.25;
|
|
2586
|
+
const newScale = Math.min(Math.max(scale + delta, 1), 5);
|
|
2587
|
+
if (newScale === 1) {
|
|
2588
|
+
resetTransform();
|
|
2589
|
+
}
|
|
2590
|
+
else {
|
|
2591
|
+
scale = newScale;
|
|
2592
|
+
applyTransform();
|
|
2593
|
+
img.style.cursor = 'zoom-out';
|
|
2594
|
+
}
|
|
2595
|
+
}, { passive: false });
|
|
2596
|
+
// Drag to pan when zoomed
|
|
2597
|
+
img.addEventListener('mousedown', (e) => {
|
|
2598
|
+
if (scale <= 1)
|
|
2599
|
+
return;
|
|
2600
|
+
e.preventDefault();
|
|
2601
|
+
isDragging = true;
|
|
2602
|
+
dragStartX = e.clientX;
|
|
2603
|
+
dragStartY = e.clientY;
|
|
2604
|
+
lastTranslateX = translateX;
|
|
2605
|
+
lastTranslateY = translateY;
|
|
2606
|
+
img.style.cursor = 'grabbing';
|
|
2607
|
+
img.style.transition = 'none';
|
|
2608
|
+
});
|
|
2609
|
+
window.addEventListener('mousemove', (e) => {
|
|
2610
|
+
if (!isDragging)
|
|
2611
|
+
return;
|
|
2612
|
+
translateX = lastTranslateX + (e.clientX - dragStartX);
|
|
2613
|
+
translateY = lastTranslateY + (e.clientY - dragStartY);
|
|
2614
|
+
applyTransform();
|
|
2615
|
+
});
|
|
2616
|
+
window.addEventListener('mouseup', () => {
|
|
2617
|
+
if (!isDragging)
|
|
2618
|
+
return;
|
|
2619
|
+
isDragging = false;
|
|
2620
|
+
img.style.cursor = scale > 1 ? 'zoom-out' : 'zoom-in';
|
|
2621
|
+
img.style.transition = 'transform 0.2s ease';
|
|
2622
|
+
});
|
|
2623
|
+
// Touch: pinch to zoom + drag to pan
|
|
2624
|
+
let lastTouchDist = 0;
|
|
2625
|
+
let lastTouchScale = 1;
|
|
2626
|
+
overlay.addEventListener('touchstart', (e) => {
|
|
2627
|
+
if (e.touches.length === 2) {
|
|
2628
|
+
e.preventDefault();
|
|
2629
|
+
const dx = e.touches[0].clientX - e.touches[1].clientX;
|
|
2630
|
+
const dy = e.touches[0].clientY - e.touches[1].clientY;
|
|
2631
|
+
lastTouchDist = Math.hypot(dx, dy);
|
|
2632
|
+
lastTouchScale = scale;
|
|
2633
|
+
}
|
|
2634
|
+
else if (e.touches.length === 1 && scale > 1) {
|
|
2635
|
+
isDragging = true;
|
|
2636
|
+
dragStartX = e.touches[0].clientX;
|
|
2637
|
+
dragStartY = e.touches[0].clientY;
|
|
2638
|
+
lastTranslateX = translateX;
|
|
2639
|
+
lastTranslateY = translateY;
|
|
2640
|
+
img.style.transition = 'none';
|
|
2641
|
+
}
|
|
2642
|
+
}, { passive: false });
|
|
2643
|
+
overlay.addEventListener('touchmove', (e) => {
|
|
2644
|
+
if (e.touches.length === 2) {
|
|
2645
|
+
e.preventDefault();
|
|
2646
|
+
const dx = e.touches[0].clientX - e.touches[1].clientX;
|
|
2647
|
+
const dy = e.touches[0].clientY - e.touches[1].clientY;
|
|
2648
|
+
const dist = Math.hypot(dx, dy);
|
|
2649
|
+
scale = Math.min(Math.max(lastTouchScale * (dist / lastTouchDist), 1), 5);
|
|
2650
|
+
if (scale === 1) {
|
|
2651
|
+
translateX = 0;
|
|
2652
|
+
translateY = 0;
|
|
2653
|
+
}
|
|
2654
|
+
applyTransform();
|
|
2655
|
+
}
|
|
2656
|
+
else if (e.touches.length === 1 && isDragging) {
|
|
2657
|
+
e.preventDefault();
|
|
2658
|
+
translateX = lastTranslateX + (e.touches[0].clientX - dragStartX);
|
|
2659
|
+
translateY = lastTranslateY + (e.touches[0].clientY - dragStartY);
|
|
2660
|
+
applyTransform();
|
|
2661
|
+
}
|
|
2662
|
+
}, { passive: false });
|
|
2663
|
+
overlay.addEventListener('touchend', (e) => {
|
|
2664
|
+
if (e.touches.length < 2) {
|
|
2665
|
+
lastTouchDist = 0;
|
|
2666
|
+
}
|
|
2667
|
+
if (e.touches.length === 0) {
|
|
2668
|
+
isDragging = false;
|
|
2669
|
+
img.style.transition = 'transform 0.2s ease';
|
|
2670
|
+
}
|
|
2671
|
+
});
|
|
2672
|
+
const close = () => {
|
|
2673
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
2674
|
+
overlay.remove();
|
|
2675
|
+
};
|
|
2676
|
+
// Only close on backdrop click when not zoomed (prevent accidental close while panning)
|
|
2677
|
+
overlay.addEventListener('click', (e) => {
|
|
2678
|
+
if (e.target === overlay && scale <= 1)
|
|
2679
|
+
close();
|
|
2680
|
+
});
|
|
2681
|
+
downloadBtn.addEventListener('click', (e) => e.stopPropagation());
|
|
2682
|
+
closeBtn.addEventListener('click', (e) => { e.stopPropagation(); close(); });
|
|
2683
|
+
// Close on Escape
|
|
2684
|
+
const handleKeyDown = (e) => {
|
|
2685
|
+
if (e.key === 'Escape')
|
|
2686
|
+
close();
|
|
2687
|
+
};
|
|
2688
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
2689
|
+
overlay.appendChild(closeBtn);
|
|
2690
|
+
overlay.appendChild(downloadBtn);
|
|
2691
|
+
overlay.appendChild(img);
|
|
2692
|
+
document.body.appendChild(overlay);
|
|
2491
2693
|
}
|
|
2492
2694
|
/**
|
|
2493
2695
|
* Initialize the SDK and render widget
|
|
@@ -2599,8 +2801,6 @@
|
|
|
2599
2801
|
console.log('[Weld SDK] Opening widget...');
|
|
2600
2802
|
this.stateCoordinator.openWidget();
|
|
2601
2803
|
this.iframeManager.showIframe(exports.IframeType.WIDGET);
|
|
2602
|
-
this.iframeManager.showIframe(exports.IframeType.BACKDROP);
|
|
2603
|
-
// Keep launcher visible so user can click it to close the widget
|
|
2604
2804
|
// Send open message to the widget iframe
|
|
2605
2805
|
const widgetIframe = this.iframeManager.getIframe(exports.IframeType.WIDGET);
|
|
2606
2806
|
if (widgetIframe?.element?.contentWindow) {
|
|
@@ -2621,8 +2821,6 @@
|
|
|
2621
2821
|
console.log('[Weld SDK] Closing widget...');
|
|
2622
2822
|
this.stateCoordinator.closeWidget();
|
|
2623
2823
|
this.iframeManager.hideIframe(exports.IframeType.WIDGET);
|
|
2624
|
-
this.iframeManager.hideIframe(exports.IframeType.BACKDROP);
|
|
2625
|
-
// Launcher stays visible
|
|
2626
2824
|
// Send close message to the widget iframe
|
|
2627
2825
|
const widgetIframe = this.iframeManager.getIframe(exports.IframeType.WIDGET);
|
|
2628
2826
|
if (widgetIframe?.element?.contentWindow) {
|