@uxbertlabs/reportly 1.0.5 → 1.0.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.
- package/dist/core/init.d.ts +1 -0
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/state.d.ts +3 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/features/annotation.d.ts +1 -1
- package/dist/features/annotation.d.ts.map +1 -1
- package/dist/features/screenshot.d.ts +1 -1
- package/dist/features/screenshot.d.ts.map +1 -1
- package/dist/reportly.cjs.js +147 -39
- package/dist/reportly.cjs.js.map +1 -1
- package/dist/reportly.esm.js +147 -39
- package/dist/reportly.esm.js.map +1 -1
- package/dist/reportly.js +147 -39
- package/dist/reportly.js.map +1 -1
- package/dist/reportly.min.js +2 -2
- package/dist/reportly.min.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/modal.d.ts +1 -0
- package/dist/ui/modal.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/reportly.esm.js
CHANGED
@@ -80,6 +80,7 @@ class State {
|
|
80
80
|
this.screenshot = null;
|
81
81
|
this.annotations = [];
|
82
82
|
this.listeners = {};
|
83
|
+
this.captureMode = 'viewport';
|
83
84
|
}
|
84
85
|
setState(newState) {
|
85
86
|
this.currentState = newState;
|
@@ -109,11 +110,18 @@ class State {
|
|
109
110
|
clearAnnotations() {
|
110
111
|
this.annotations = [];
|
111
112
|
}
|
113
|
+
setCaptureMode(mode) {
|
114
|
+
this.captureMode = mode;
|
115
|
+
}
|
116
|
+
getCaptureMode() {
|
117
|
+
return this.captureMode;
|
118
|
+
}
|
112
119
|
reset() {
|
113
120
|
this.currentState = STATE.IDLE;
|
114
121
|
this.currentIssue = null;
|
115
122
|
this.screenshot = null;
|
116
123
|
this.annotations = [];
|
124
|
+
this.captureMode = 'viewport';
|
117
125
|
}
|
118
126
|
// Event system
|
119
127
|
on(event, callback) {
|
@@ -187,6 +195,20 @@ class Modal {
|
|
187
195
|
</div>
|
188
196
|
|
189
197
|
<form class="uxbert-form" id="uxbert-issue-form">
|
198
|
+
<div class="uxbert-form-group">
|
199
|
+
<label class="uxbert-form-label">Capture Mode</label>
|
200
|
+
<div class="uxbert-capture-mode">
|
201
|
+
<label class="uxbert-radio-label">
|
202
|
+
<input type="radio" name="capture-mode" value="viewport" id="uxbert-capture-viewport" checked />
|
203
|
+
<span>Current View</span>
|
204
|
+
</label>
|
205
|
+
<label class="uxbert-radio-label">
|
206
|
+
<input type="radio" name="capture-mode" value="fullpage" id="uxbert-capture-fullpage" />
|
207
|
+
<span>Full Page</span>
|
208
|
+
</label>
|
209
|
+
</div>
|
210
|
+
</div>
|
211
|
+
|
190
212
|
<div class="uxbert-form-group">
|
191
213
|
<label class="uxbert-form-label" for="uxbert-title">Issue Title *</label>
|
192
214
|
<input
|
@@ -217,6 +239,12 @@ class Modal {
|
|
217
239
|
</select>
|
218
240
|
</div>
|
219
241
|
|
242
|
+
<div class="uxbert-capture-action" id="uxbert-capture-action">
|
243
|
+
<button type="button" class="uxbert-btn uxbert-btn-primary" id="uxbert-capture-btn">
|
244
|
+
📸 Take Screenshot
|
245
|
+
</button>
|
246
|
+
</div>
|
247
|
+
|
220
248
|
<div class="uxbert-screenshot-preview" id="uxbert-screenshot-container" style="display: none;">
|
221
249
|
<img id="uxbert-screenshot-img" src="" alt="Screenshot" />
|
222
250
|
<div class="uxbert-screenshot-actions">
|
@@ -233,7 +261,7 @@ class Modal {
|
|
233
261
|
<button type="button" class="uxbert-btn uxbert-btn-secondary" id="uxbert-cancel-btn">
|
234
262
|
Cancel
|
235
263
|
</button>
|
236
|
-
<button type="submit" class="uxbert-btn uxbert-btn-primary">
|
264
|
+
<button type="submit" class="uxbert-btn uxbert-btn-primary" id="uxbert-submit-btn">
|
237
265
|
📥 Download JSON
|
238
266
|
</button>
|
239
267
|
</div>
|
@@ -266,6 +294,13 @@ class Modal {
|
|
266
294
|
e.preventDefault();
|
267
295
|
this.handleSubmit();
|
268
296
|
});
|
297
|
+
// Capture button
|
298
|
+
const captureBtn = this.modal.querySelector('#uxbert-capture-btn');
|
299
|
+
captureBtn.addEventListener('click', () => {
|
300
|
+
if (this.callbacks.onCapture) {
|
301
|
+
this.callbacks.onCapture();
|
302
|
+
}
|
303
|
+
});
|
269
304
|
// Annotate button
|
270
305
|
const annotateBtn = this.modal.querySelector('#uxbert-annotate-btn');
|
271
306
|
annotateBtn.addEventListener('click', () => {
|
@@ -318,14 +353,26 @@ class Modal {
|
|
318
353
|
return;
|
319
354
|
const container = this.modal.querySelector('#uxbert-screenshot-container');
|
320
355
|
const img = this.modal.querySelector('#uxbert-screenshot-img');
|
356
|
+
const captureAction = this.modal.querySelector('#uxbert-capture-action');
|
357
|
+
const submitBtn = this.modal.querySelector('#uxbert-submit-btn');
|
321
358
|
if (screenshot) {
|
322
359
|
img.src = screenshot;
|
323
360
|
container.style.display = 'block';
|
361
|
+
captureAction.style.display = 'none';
|
362
|
+
submitBtn.disabled = false;
|
324
363
|
}
|
325
364
|
else {
|
326
365
|
container.style.display = 'none';
|
366
|
+
captureAction.style.display = 'block';
|
367
|
+
submitBtn.disabled = true;
|
327
368
|
}
|
328
369
|
}
|
370
|
+
getCaptureMode() {
|
371
|
+
if (!this.modal)
|
372
|
+
return 'viewport';
|
373
|
+
const viewportRadio = this.modal.querySelector('#uxbert-capture-viewport');
|
374
|
+
return viewportRadio.checked ? 'viewport' : 'fullpage';
|
375
|
+
}
|
329
376
|
reset() {
|
330
377
|
if (!this.modal)
|
331
378
|
return;
|
@@ -9400,26 +9447,43 @@ class Screenshot {
|
|
9400
9447
|
constructor() {
|
9401
9448
|
this.currentScreenshot = null;
|
9402
9449
|
}
|
9403
|
-
async capture() {
|
9450
|
+
async capture(mode = 'fullpage') {
|
9404
9451
|
try {
|
9405
9452
|
// Hide UXbert UI elements before capturing
|
9406
9453
|
this.hideUXbertElements();
|
9407
|
-
// Scroll to top to capture full page
|
9408
9454
|
const originalScrollY = window.scrollY;
|
9409
|
-
|
9410
|
-
|
9411
|
-
|
9412
|
-
|
9413
|
-
|
9414
|
-
|
9415
|
-
|
9416
|
-
|
9417
|
-
|
9418
|
-
|
9419
|
-
|
9420
|
-
|
9421
|
-
|
9422
|
-
|
9455
|
+
let canvas;
|
9456
|
+
if (mode === 'viewport') {
|
9457
|
+
// Capture only the current viewport
|
9458
|
+
canvas = await html2canvas(document.body, {
|
9459
|
+
allowTaint: true,
|
9460
|
+
useCORS: true,
|
9461
|
+
logging: false,
|
9462
|
+
width: window.innerWidth,
|
9463
|
+
height: window.innerHeight,
|
9464
|
+
windowWidth: window.innerWidth,
|
9465
|
+
windowHeight: window.innerHeight,
|
9466
|
+
x: window.scrollX,
|
9467
|
+
y: window.scrollY,
|
9468
|
+
});
|
9469
|
+
}
|
9470
|
+
else {
|
9471
|
+
// Scroll to top to capture full page
|
9472
|
+
window.scrollTo(0, 0);
|
9473
|
+
// Get full page dimensions
|
9474
|
+
const fullPageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
|
9475
|
+
const fullPageWidth = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
|
9476
|
+
// Capture the full page
|
9477
|
+
canvas = await html2canvas(document.body, {
|
9478
|
+
allowTaint: true,
|
9479
|
+
useCORS: true,
|
9480
|
+
logging: false,
|
9481
|
+
width: fullPageWidth,
|
9482
|
+
height: fullPageHeight,
|
9483
|
+
});
|
9484
|
+
// Restore scroll position
|
9485
|
+
window.scrollTo(0, originalScrollY);
|
9486
|
+
}
|
9423
9487
|
// Show UXbert UI elements again
|
9424
9488
|
this.showUXbertElements();
|
9425
9489
|
// Convert to base64
|
@@ -9495,29 +9559,46 @@ class AnnotationManager {
|
|
9495
9559
|
document.body.appendChild(this.canvas);
|
9496
9560
|
return this.canvas;
|
9497
9561
|
}
|
9498
|
-
updateCanvasSize() {
|
9562
|
+
updateCanvasSize(mode = 'fullpage') {
|
9499
9563
|
if (!this.canvas)
|
9500
9564
|
return;
|
9501
|
-
|
9502
|
-
|
9503
|
-
|
9504
|
-
|
9505
|
-
|
9565
|
+
if (mode === 'viewport') {
|
9566
|
+
// Set canvas to viewport dimensions
|
9567
|
+
this.canvas.width = window.innerWidth;
|
9568
|
+
this.canvas.height = window.innerHeight;
|
9569
|
+
}
|
9570
|
+
else {
|
9571
|
+
// Get full page dimensions
|
9572
|
+
const fullPageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
|
9573
|
+
const fullPageWidth = Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);
|
9574
|
+
this.canvas.width = fullPageWidth;
|
9575
|
+
this.canvas.height = fullPageHeight;
|
9576
|
+
}
|
9506
9577
|
}
|
9507
|
-
show() {
|
9578
|
+
show(mode = 'fullpage') {
|
9508
9579
|
if (this.canvas && this.ctx) {
|
9509
9580
|
// Update canvas size to match current page dimensions
|
9510
|
-
this.updateCanvasSize();
|
9581
|
+
this.updateCanvasSize(mode);
|
9511
9582
|
// Reset context properties after resize
|
9512
9583
|
this.ctx.lineCap = 'round';
|
9513
9584
|
this.ctx.lineJoin = 'round';
|
9514
9585
|
this.canvas.classList.add('active');
|
9586
|
+
// If viewport mode, add viewport-mode class
|
9587
|
+
if (mode === 'viewport') {
|
9588
|
+
this.canvas.classList.add('viewport-mode');
|
9589
|
+
// Note: We don't disable scrolling in viewport mode to allow users to scroll
|
9590
|
+
// and annotate different parts of the viewport
|
9591
|
+
}
|
9592
|
+
else {
|
9593
|
+
this.canvas.classList.remove('viewport-mode');
|
9594
|
+
}
|
9515
9595
|
this.redraw();
|
9516
9596
|
}
|
9517
9597
|
}
|
9518
9598
|
hide() {
|
9519
9599
|
if (this.canvas) {
|
9520
9600
|
this.canvas.classList.remove('active');
|
9601
|
+
this.canvas.classList.remove('viewport-mode');
|
9521
9602
|
}
|
9522
9603
|
// Clean up any active text input
|
9523
9604
|
this.removeTextInput();
|
@@ -9530,10 +9611,13 @@ class AnnotationManager {
|
|
9530
9611
|
this.currentColor = color;
|
9531
9612
|
}
|
9532
9613
|
handleMouseDown(e) {
|
9614
|
+
const isViewportMode = this.canvas?.classList.contains('viewport-mode');
|
9615
|
+
const scrollOffsetX = isViewportMode ? 0 : window.scrollX;
|
9616
|
+
const scrollOffsetY = isViewportMode ? 0 : window.scrollY;
|
9533
9617
|
// Handle text tool separately
|
9534
9618
|
if (this.currentTool === 'text') {
|
9535
|
-
const x = e.clientX +
|
9536
|
-
const y = e.clientY +
|
9619
|
+
const x = e.clientX + scrollOffsetX;
|
9620
|
+
const y = e.clientY + scrollOffsetY;
|
9537
9621
|
// Check if clicking on existing text to edit
|
9538
9622
|
const clickedText = this.getTextAnnotationAt(x, y);
|
9539
9623
|
if (clickedText) {
|
@@ -9545,15 +9629,18 @@ class AnnotationManager {
|
|
9545
9629
|
return;
|
9546
9630
|
}
|
9547
9631
|
this.isDrawing = true;
|
9548
|
-
this.startX = e.clientX +
|
9549
|
-
this.startY = e.clientY +
|
9632
|
+
this.startX = e.clientX + scrollOffsetX;
|
9633
|
+
this.startY = e.clientY + scrollOffsetY;
|
9550
9634
|
this.currentPath = [{ x: this.startX, y: this.startY }];
|
9551
9635
|
}
|
9552
9636
|
handleMouseMove(e) {
|
9553
9637
|
if (!this.isDrawing || !this.ctx)
|
9554
9638
|
return;
|
9555
|
-
const
|
9556
|
-
const
|
9639
|
+
const isViewportMode = this.canvas?.classList.contains('viewport-mode');
|
9640
|
+
const scrollOffsetX = isViewportMode ? 0 : window.scrollX;
|
9641
|
+
const scrollOffsetY = isViewportMode ? 0 : window.scrollY;
|
9642
|
+
const x = e.clientX + scrollOffsetX;
|
9643
|
+
const y = e.clientY + scrollOffsetY;
|
9557
9644
|
if (this.currentTool === 'pen') {
|
9558
9645
|
this.currentPath.push({ x, y });
|
9559
9646
|
this.redraw();
|
@@ -9573,8 +9660,11 @@ class AnnotationManager {
|
|
9573
9660
|
if (!this.isDrawing)
|
9574
9661
|
return;
|
9575
9662
|
this.isDrawing = false;
|
9576
|
-
const
|
9577
|
-
const
|
9663
|
+
const isViewportMode = this.canvas?.classList.contains('viewport-mode');
|
9664
|
+
const scrollOffsetX = isViewportMode ? 0 : window.scrollX;
|
9665
|
+
const scrollOffsetY = isViewportMode ? 0 : window.scrollY;
|
9666
|
+
const x = e.clientX + scrollOffsetX;
|
9667
|
+
const y = e.clientY + scrollOffsetY;
|
9578
9668
|
// Save the annotation
|
9579
9669
|
if (this.currentTool === 'pen') {
|
9580
9670
|
this.annotations.push({
|
@@ -10047,7 +10137,7 @@ function styleInject(css, ref) {
|
|
10047
10137
|
}
|
10048
10138
|
}
|
10049
10139
|
|
10050
|
-
var css_248z = ":root{--uxbert-primary:#4f46e5;--uxbert-primary-hover:#4338ca;--uxbert-danger:#ef4444;--uxbert-success:#10b981;--uxbert-bg:#fff;--uxbert-text:#1f2937;--uxbert-border:#e5e7eb;--uxbert-shadow:0 10px 25px rgba(0,0,0,.1);--uxbert-z-button:999999;--uxbert-z-modal:1000000;--uxbert-z-canvas:1000001;--uxbert-z-toolbar:1000002}[data-theme=dark]{--uxbert-bg:#1f2937;--uxbert-text:#f9fafb;--uxbert-border:#374151}.uxbert-fab{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:flex;font-size:24px;height:56px;justify-content:center;position:fixed;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-button)}.uxbert-fab:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-fab.bottom-right{bottom:24px;right:24px}.uxbert-fab.bottom-left{bottom:24px;left:24px}.uxbert-fab.top-right{right:24px;top:24px}.uxbert-fab.top-left{left:24px;top:24px}.uxbert-overlay{align-items:center;animation:fadeIn .3s ease;background:rgba(0,0,0,.5);display:none;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:var(--uxbert-z-modal)}.uxbert-overlay.active{display:flex}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.uxbert-modal{animation:slideUp .3s ease;background:var(--uxbert-bg);border-radius:12px;box-shadow:var(--uxbert-shadow);color:var(--uxbert-text);max-height:90vh;max-width:600px;overflow-y:auto;padding:24px;width:90%}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.uxbert-modal-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:20px}.uxbert-modal-title{font-size:20px;font-weight:600;margin:0}.uxbert-modal-close{align-items:center;background:none;border:none;border-radius:4px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:24px;height:32px;justify-content:center;padding:0;width:32px}.uxbert-modal-close:hover{background:var(--uxbert-border)}.uxbert-form-group{margin-bottom:16px}.uxbert-form-label{display:block;font-size:14px;font-weight:500;margin-bottom:8px}.uxbert-form-input,.uxbert-form-select,.uxbert-form-textarea{background:var(--uxbert-bg);border:1px solid var(--uxbert-border);border-radius:6px;box-sizing:border-box;color:var(--uxbert-text);font-family:inherit;font-size:14px;padding:10px;width:100%}.uxbert-form-textarea{min-height:100px;resize:vertical}.uxbert-form-input:focus,.uxbert-form-select:focus,.uxbert-form-textarea:focus{border-color:var(--uxbert-primary);outline:none}.uxbert-screenshot-preview{border:1px solid var(--uxbert-border);border-radius:8px;margin:16px 0;overflow:hidden}.uxbert-screenshot-preview img{display:block;width:100%}.uxbert-screenshot-actions{background:var(--uxbert-border);display:flex;gap:8px;padding:12px}.uxbert-btn{align-items:center;border:none;border-radius:6px;cursor:pointer;display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:10px 20px;transition:all .2s ease}.uxbert-btn-primary{background:var(--uxbert-primary);color:#fff}.uxbert-btn-primary:hover{background:var(--uxbert-primary-hover)}.uxbert-btn-secondary{background:var(--uxbert-border);color:var(--uxbert-text)}.uxbert-btn-secondary:hover{background:#d1d5db}.uxbert-btn-danger{background:var(--uxbert-danger);color:#fff}.uxbert-btn-danger:hover{background:#dc2626}.uxbert-modal-actions{display:flex;gap:12px;justify-content:flex-end;margin-top:20px}.uxbert-toolbar-toggle{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;bottom:24px;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:none;font-size:24px;height:56px;justify-content:center;position:fixed;right:24px;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar-toggle.active{display:flex}.uxbert-toolbar-toggle.hidden{opacity:0;pointer-events:none;transform:scale(.8)}.uxbert-toolbar-toggle:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-toolbar{background:var(--uxbert-bg);border-radius:12px;bottom:24px;box-shadow:var(--uxbert-shadow);display:none;flex-direction:column;gap:8px;max-height:80vh;opacity:0;overflow-y:auto;padding:16px;pointer-events:none;position:fixed;right:24px;transform:translateY(20px);transition:all .3s ease;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar.active{display:flex}.uxbert-toolbar.expanded{opacity:1;pointer-events:all;transform:translateY(0)}.uxbert-toolbar-header{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-bottom:8px}.uxbert-toolbar-title{flex:1;font-size:14px;font-weight:600}.uxbert-toolbar-exit,.uxbert-toolbar-minimize{align-items:center;background:var(--uxbert-border);border:none;border-radius:6px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:20px;font-weight:700;height:32px;justify-content:center;transition:all .2s ease;width:32px}.uxbert-toolbar-exit{background:var(--uxbert-danger);color:#fff}.uxbert-toolbar-minimize:hover{background:#d1d5db;transform:scale(1.1)}.uxbert-toolbar-exit:hover{background:#dc2626;transform:scale(1.1)}.uxbert-toolbar-tools{display:flex;flex-wrap:wrap;gap:8px}.uxbert-tool-btn{align-items:center;background:var(--uxbert-bg);border:2px solid var(--uxbert-border);border-radius:6px;cursor:pointer;display:flex;font-family:Arial,sans-serif;font-size:18px;font-weight:700;height:40px;justify-content:center;transition:all .2s ease;width:40px}.uxbert-tool-btn.active,.uxbert-tool-btn:hover{background:var(--uxbert-primary);border-color:var(--uxbert-primary);color:#fff}.uxbert-color-picker{display:flex;gap:6px;margin:8px 0}.uxbert-color-option{border:2px solid var(--uxbert-border);border-radius:50%;cursor:pointer;height:32px;transition:transform .2s ease;width:32px}.uxbert-color-option:hover{transform:scale(1.1)}.uxbert-color-option.active{border:3px solid var(--uxbert-text)}.uxbert-canvas-overlay{cursor:crosshair;display:none;left:0;position:absolute;top:0;z-index:var(--uxbert-z-canvas)}.uxbert-canvas-overlay.active{display:block}.uxbert-text-input{background:hsla(0,0%,100%,.95);border:2px solid var(--uxbert-primary);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--uxbert-text);font-family:Arial,sans-serif;font-size:16px;font-weight:700;min-width:200px;outline:none;padding:8px 12px;z-index:var(--uxbert-z-toolbar)}.uxbert-text-input:focus{border-color:var(--uxbert-primary-hover);box-shadow:0 4px 16px rgba(79,70,229,.3)}.uxbert-text-input::placeholder{color:#9ca3af;font-weight:400}@media (max-width:768px){.uxbert-modal{max-height:95vh;padding:16px;width:95%}.uxbert-toolbar{bottom:90px;left:16px;max-height:60vh;right:16px;width:auto}.uxbert-toolbar-toggle{bottom:16px;height:56px;right:16px;width:56px}.uxbert-fab{font-size:20px;height:48px;width:48px}.uxbert-color-picker,.uxbert-toolbar-tools{justify-content:center}}";
|
10140
|
+
var css_248z = ":root{--uxbert-primary:#4f46e5;--uxbert-primary-hover:#4338ca;--uxbert-danger:#ef4444;--uxbert-success:#10b981;--uxbert-bg:#fff;--uxbert-text:#1f2937;--uxbert-border:#e5e7eb;--uxbert-shadow:0 10px 25px rgba(0,0,0,.1);--uxbert-z-button:999999;--uxbert-z-modal:1000000;--uxbert-z-canvas:1000001;--uxbert-z-toolbar:1000002}[data-theme=dark]{--uxbert-bg:#1f2937;--uxbert-text:#f9fafb;--uxbert-border:#374151}.uxbert-fab{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:flex;font-size:24px;height:56px;justify-content:center;position:fixed;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-button)}.uxbert-fab:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-fab.bottom-right{bottom:24px;right:24px}.uxbert-fab.bottom-left{bottom:24px;left:24px}.uxbert-fab.top-right{right:24px;top:24px}.uxbert-fab.top-left{left:24px;top:24px}.uxbert-overlay{align-items:center;animation:fadeIn .3s ease;background:rgba(0,0,0,.5);display:none;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:var(--uxbert-z-modal)}.uxbert-overlay.active{display:flex}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.uxbert-modal{animation:slideUp .3s ease;background:var(--uxbert-bg);border-radius:12px;box-shadow:var(--uxbert-shadow);color:var(--uxbert-text);max-height:90vh;max-width:600px;overflow-y:auto;padding:24px;width:90%}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.uxbert-modal-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:20px}.uxbert-modal-title{font-size:20px;font-weight:600;margin:0}.uxbert-modal-close{align-items:center;background:none;border:none;border-radius:4px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:24px;height:32px;justify-content:center;padding:0;width:32px}.uxbert-modal-close:hover{background:var(--uxbert-border)}.uxbert-form-group{margin-bottom:16px}.uxbert-form-label{display:block;font-size:14px;font-weight:500;margin-bottom:8px}.uxbert-capture-mode{display:flex;flex-wrap:wrap;gap:12px}.uxbert-radio-label{align-items:center;border:2px solid var(--uxbert-border);border-radius:8px;cursor:pointer;display:flex;flex:1;gap:8px;min-width:140px;padding:10px 16px;transition:all .2s ease}.uxbert-radio-label:hover{background:rgba(79,70,229,.05);border-color:var(--uxbert-primary)}.uxbert-radio-label input[type=radio]{cursor:pointer;height:18px;margin:0;width:18px}.uxbert-radio-label input[type=radio]:checked{accent-color:var(--uxbert-primary)}.uxbert-radio-label:has(input[type=radio]:checked){background:rgba(79,70,229,.1);border-color:var(--uxbert-primary)}.uxbert-radio-label span{flex:1;font-size:14px;font-weight:500}.uxbert-form-input,.uxbert-form-select,.uxbert-form-textarea{background:var(--uxbert-bg);border:1px solid var(--uxbert-border);border-radius:6px;box-sizing:border-box;color:var(--uxbert-text);font-family:inherit;font-size:14px;padding:10px;width:100%}.uxbert-form-textarea{min-height:100px;resize:vertical}.uxbert-form-input:focus,.uxbert-form-select:focus,.uxbert-form-textarea:focus{border-color:var(--uxbert-primary);outline:none}.uxbert-capture-action{margin:16px 0;text-align:center}.uxbert-capture-action .uxbert-btn{min-width:200px}.uxbert-screenshot-preview{border:1px solid var(--uxbert-border);border-radius:8px;margin:16px 0;overflow:hidden}.uxbert-screenshot-preview img{display:block;width:100%}.uxbert-screenshot-actions{background:var(--uxbert-border);display:flex;gap:8px;padding:12px}.uxbert-btn{align-items:center;border:none;border-radius:6px;cursor:pointer;display:inline-flex;font-size:14px;font-weight:500;gap:8px;padding:10px 20px;transition:all .2s ease}.uxbert-btn-primary{background:var(--uxbert-primary);color:#fff}.uxbert-btn-primary:hover{background:var(--uxbert-primary-hover)}.uxbert-btn-secondary{background:var(--uxbert-border);color:var(--uxbert-text)}.uxbert-btn-secondary:hover{background:#d1d5db}.uxbert-btn-danger{background:var(--uxbert-danger);color:#fff}.uxbert-btn-danger:hover{background:#dc2626}.uxbert-modal-actions{display:flex;gap:12px;justify-content:flex-end;margin-top:20px}.uxbert-toolbar-toggle{align-items:center;background:var(--uxbert-primary);border:none;border-radius:50%;bottom:24px;box-shadow:var(--uxbert-shadow);color:#fff;cursor:pointer;display:none;font-size:24px;height:56px;justify-content:center;position:fixed;right:24px;transition:all .3s ease;width:56px;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar-toggle.active{display:flex}.uxbert-toolbar-toggle.hidden{opacity:0;pointer-events:none;transform:scale(.8)}.uxbert-toolbar-toggle:hover{background:var(--uxbert-primary-hover);transform:scale(1.1)}.uxbert-toolbar{background:var(--uxbert-bg);border-radius:12px;bottom:24px;box-shadow:var(--uxbert-shadow);display:none;flex-direction:column;gap:8px;max-height:80vh;opacity:0;overflow-y:auto;padding:16px;pointer-events:none;position:fixed;right:24px;transform:translateY(20px);transition:all .3s ease;z-index:var(--uxbert-z-toolbar)}.uxbert-toolbar.active{display:flex}.uxbert-toolbar.expanded{opacity:1;pointer-events:all;transform:translateY(0)}.uxbert-toolbar-header{align-items:center;display:flex;gap:8px;justify-content:space-between;margin-bottom:8px}.uxbert-toolbar-title{flex:1;font-size:14px;font-weight:600}.uxbert-toolbar-exit,.uxbert-toolbar-minimize{align-items:center;background:var(--uxbert-border);border:none;border-radius:6px;color:var(--uxbert-text);cursor:pointer;display:flex;font-size:20px;font-weight:700;height:32px;justify-content:center;transition:all .2s ease;width:32px}.uxbert-toolbar-exit{background:var(--uxbert-danger);color:#fff}.uxbert-toolbar-minimize:hover{background:#d1d5db;transform:scale(1.1)}.uxbert-toolbar-exit:hover{background:#dc2626;transform:scale(1.1)}.uxbert-toolbar-tools{display:flex;flex-wrap:wrap;gap:8px}.uxbert-tool-btn{align-items:center;background:var(--uxbert-bg);border:2px solid var(--uxbert-border);border-radius:6px;cursor:pointer;display:flex;font-family:Arial,sans-serif;font-size:18px;font-weight:700;height:40px;justify-content:center;transition:all .2s ease;width:40px}.uxbert-tool-btn.active,.uxbert-tool-btn:hover{background:var(--uxbert-primary);border-color:var(--uxbert-primary);color:#fff}.uxbert-color-picker{display:flex;gap:6px;margin:8px 0}.uxbert-color-option{border:2px solid var(--uxbert-border);border-radius:50%;cursor:pointer;height:32px;transition:transform .2s ease;width:32px}.uxbert-color-option:hover{transform:scale(1.1)}.uxbert-color-option.active{border:3px solid var(--uxbert-text)}.uxbert-canvas-overlay{cursor:crosshair;display:none;left:0;position:absolute;top:0;z-index:var(--uxbert-z-canvas)}.uxbert-canvas-overlay.active{display:block}.uxbert-canvas-overlay.viewport-mode{left:0;position:fixed;top:0}.uxbert-text-input{background:hsla(0,0%,100%,.95);border:2px solid var(--uxbert-primary);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.15);color:var(--uxbert-text);font-family:Arial,sans-serif;font-size:16px;font-weight:700;min-width:200px;outline:none;padding:8px 12px;z-index:var(--uxbert-z-toolbar)}.uxbert-text-input:focus{border-color:var(--uxbert-primary-hover);box-shadow:0 4px 16px rgba(79,70,229,.3)}.uxbert-text-input::placeholder{color:#9ca3af;font-weight:400}@media (max-width:768px){.uxbert-modal{max-height:95vh;padding:16px;width:95%}.uxbert-toolbar{bottom:90px;left:16px;max-height:60vh;right:16px;width:auto}.uxbert-toolbar-toggle{bottom:16px;height:56px;right:16px;width:56px}.uxbert-fab{font-size:20px;height:48px;width:48px}.uxbert-color-picker,.uxbert-toolbar-tools{justify-content:center}}";
|
10051
10141
|
styleInject(css_248z);
|
10052
10142
|
|
10053
10143
|
// Main initialization file
|
@@ -10089,6 +10179,7 @@ class Reportly {
|
|
10089
10179
|
onClose: () => this.handleModalClose(),
|
10090
10180
|
onAnnotate: () => this.startAnnotation(),
|
10091
10181
|
onRetake: () => this.retakeScreenshot(),
|
10182
|
+
onCapture: () => this.captureWithMode(),
|
10092
10183
|
});
|
10093
10184
|
this.toolbar = new Toolbar({
|
10094
10185
|
onToolChange: (tool) => this.annotation?.setTool(tool),
|
@@ -10119,14 +10210,27 @@ class Reportly {
|
|
10119
10210
|
});
|
10120
10211
|
}
|
10121
10212
|
async handleButtonClick() {
|
10213
|
+
try {
|
10214
|
+
// Open modal first to let user choose capture mode
|
10215
|
+
this.modal?.open();
|
10216
|
+
}
|
10217
|
+
catch (error) {
|
10218
|
+
console.error("Failed to open modal:", error);
|
10219
|
+
alert("Failed to open modal. Please try again.");
|
10220
|
+
}
|
10221
|
+
}
|
10222
|
+
async captureWithMode() {
|
10122
10223
|
try {
|
10123
10224
|
this.state?.setState(STATE.CAPTURING);
|
10225
|
+
// Get capture mode from modal
|
10226
|
+
const captureMode = this.modal?.getCaptureMode() || 'viewport';
|
10227
|
+
// Save capture mode in state
|
10228
|
+
this.state?.setCaptureMode(captureMode);
|
10124
10229
|
// Capture screenshot
|
10125
|
-
const screenshot = await this.screenshot.capture();
|
10230
|
+
const screenshot = await this.screenshot.capture(captureMode);
|
10126
10231
|
this.state?.setScreenshot(screenshot);
|
10127
10232
|
// Show modal with screenshot
|
10128
10233
|
this.modal?.setScreenshot(screenshot);
|
10129
|
-
this.modal?.open();
|
10130
10234
|
this.state?.setState(STATE.IDLE);
|
10131
10235
|
}
|
10132
10236
|
catch (error) {
|
@@ -10139,7 +10243,8 @@ class Reportly {
|
|
10139
10243
|
this.state?.setState(STATE.ANNOTATING);
|
10140
10244
|
this.modal?.close();
|
10141
10245
|
this.button?.hide();
|
10142
|
-
this.
|
10246
|
+
const captureMode = this.state?.getCaptureMode() || 'viewport';
|
10247
|
+
this.annotation?.show(captureMode);
|
10143
10248
|
this.toolbar?.show();
|
10144
10249
|
}
|
10145
10250
|
exitAnnotation() {
|
@@ -10175,13 +10280,16 @@ class Reportly {
|
|
10175
10280
|
}
|
10176
10281
|
async retakeScreenshot() {
|
10177
10282
|
try {
|
10283
|
+
// Get the current capture mode from modal before closing
|
10284
|
+
const captureMode = this.modal?.getCaptureMode() || 'viewport';
|
10178
10285
|
this.modal?.close();
|
10179
10286
|
this.state?.setState(STATE.CAPTURING);
|
10180
10287
|
// Clear previous annotations
|
10181
10288
|
this.annotation?.clear();
|
10182
|
-
// Capture new screenshot
|
10183
|
-
const screenshot = await this.screenshot.capture();
|
10289
|
+
// Capture new screenshot with the same mode
|
10290
|
+
const screenshot = await this.screenshot.capture(captureMode);
|
10184
10291
|
this.state?.setScreenshot(screenshot);
|
10292
|
+
this.state?.setCaptureMode(captureMode);
|
10185
10293
|
// Show modal with new screenshot
|
10186
10294
|
this.modal?.setScreenshot(screenshot);
|
10187
10295
|
this.modal?.open();
|