glitchgrab 1.0.1 → 1.2.0

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/index.mjs CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  } from "react";
11
11
 
12
12
  // src/error-boundary.tsx
13
- import React from "react";
13
+ import * as React from "react";
14
14
 
15
15
  // src/breadcrumbs.ts
16
16
  var MAX_DEFAULT = 50;
@@ -329,6 +329,7 @@ function useGlitchgrab() {
329
329
  }
330
330
  function GlitchgrabProviderInner({
331
331
  token,
332
+ session,
332
333
  baseUrl,
333
334
  onError,
334
335
  onReportSent,
@@ -383,6 +384,7 @@ function GlitchgrabProviderInner({
383
384
  useEffect(() => {
384
385
  try {
385
386
  if (typeof window === "undefined") return;
387
+ if (process.env.NODE_ENV === "development") return;
386
388
  const handleError = (event) => {
387
389
  var _a, _b, _c, _d, _e;
388
390
  try {
@@ -402,7 +404,10 @@ function GlitchgrabProviderInner({
402
404
  visitedPages: JSON.stringify(context.visitedPages),
403
405
  filename: (_c = event.filename) != null ? _c : "",
404
406
  lineno: String((_d = event.lineno) != null ? _d : ""),
405
- colno: String((_e = event.colno) != null ? _e : "")
407
+ colno: String((_e = event.colno) != null ? _e : ""),
408
+ ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
409
+ ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
410
+ ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
406
411
  }
407
412
  };
408
413
  sendReport(payload, baseUrl).then((result) => {
@@ -430,7 +435,10 @@ function GlitchgrabProviderInner({
430
435
  metadata: {
431
436
  timestamp: context.timestamp,
432
437
  visitedPages: JSON.stringify(context.visitedPages),
433
- type: "unhandledrejection"
438
+ type: "unhandledrejection",
439
+ ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
440
+ ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
441
+ ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {}
434
442
  }
435
443
  };
436
444
  sendReport(payload, baseUrl).then((result) => {
@@ -466,6 +474,10 @@ function GlitchgrabProviderInner({
466
474
  metadata: {
467
475
  timestamp: context.timestamp,
468
476
  visitedPages: JSON.stringify(context.visitedPages),
477
+ ...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
478
+ ...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
479
+ ...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {},
480
+ ...(session == null ? void 0 : session.phone) ? { sessionUserPhone: String(session.phone) } : {},
469
481
  ...metadata
470
482
  }
471
483
  };
@@ -513,47 +525,103 @@ function GlitchgrabProviderInner({
513
525
  );
514
526
  }
515
527
  function GlitchgrabProvider(props) {
528
+ if (!props.token) return /* @__PURE__ */ jsx(Fragment, { children: props.children });
529
+ const resolvedProps = {
530
+ ...props,
531
+ baseUrl: props.baseUrl || (typeof window !== "undefined" ? window.location.origin : DEFAULT_BASE_URL2)
532
+ };
516
533
  try {
517
- return /* @__PURE__ */ jsx(GlitchgrabProviderInner, { ...props });
534
+ return /* @__PURE__ */ jsx(GlitchgrabProviderInner, { ...resolvedProps });
518
535
  } catch (e) {
519
536
  return /* @__PURE__ */ jsx(Fragment, { children: props.children });
520
537
  }
521
538
  }
522
539
 
523
540
  // src/report-button.tsx
524
- import { useState, useRef as useRef2, useEffect as useEffect2 } from "react";
541
+ import { useState as useState2, useRef as useRef2, useEffect as useEffect2 } from "react";
525
542
  import { Fragment as Fragment2, jsx as jsx2, jsxs } from "react/jsx-runtime";
526
543
  function ReportButton({
527
544
  position = "bottom-right",
528
545
  label = "Report Bug",
529
- className
546
+ className,
547
+ children
530
548
  }) {
531
- const [isOpen, setIsOpen] = useState(false);
532
- const [description, setDescription] = useState("");
533
- const [isSubmitting, setIsSubmitting] = useState(false);
534
- const [submitted, setSubmitted] = useState(false);
549
+ var _a, _b;
550
+ const [capturing, setCapturing] = useState2(false);
551
+ const [isOpen, setIsOpen] = useState2(false);
552
+ const [description, setDescription] = useState2("");
553
+ const [isSubmitting, setIsSubmitting] = useState2(false);
554
+ const [submitted, setSubmitted] = useState2(false);
555
+ const [screenshot, setScreenshot] = useState2(null);
556
+ const [previewOpen, setPreviewOpen] = useState2(false);
557
+ const fileInputRef = useRef2(null);
535
558
  const modalRef = useRef2(null);
536
559
  const { reportBug } = useGlitchgrab();
537
- useEffect2(() => {
560
+ const handleFileUpload = (e) => {
561
+ var _a2;
562
+ const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
563
+ if (!file) return;
564
+ const reader = new FileReader();
565
+ reader.onload = () => {
566
+ setScreenshot(reader.result);
567
+ };
568
+ reader.readAsDataURL(file);
569
+ e.target.value = "";
570
+ };
571
+ const retakeScreenshot = async () => {
572
+ setPreviewOpen(false);
573
+ setIsOpen(false);
574
+ setScreenshot(null);
575
+ await new Promise((r) => setTimeout(r, 300));
538
576
  try {
539
- if (!isOpen) return;
540
- const handleClickOutside = (event) => {
541
- if (modalRef.current && !modalRef.current.contains(event.target)) {
542
- setIsOpen(false);
543
- }
544
- };
545
- document.addEventListener("mousedown", handleClickOutside);
546
- return () => document.removeEventListener("mousedown", handleClickOutside);
577
+ const { default: html2canvas } = await import("html2canvas-pro");
578
+ const canvas = await html2canvas(document.body, {
579
+ scale: 0.5,
580
+ logging: false,
581
+ useCORS: true,
582
+ allowTaint: true
583
+ });
584
+ setScreenshot(canvas.toDataURL("image/jpeg", 0.6));
585
+ } catch (e) {
586
+ }
587
+ setIsOpen(true);
588
+ };
589
+ const handleOpen = async () => {
590
+ setCapturing(true);
591
+ setSubmitted(false);
592
+ try {
593
+ const { default: html2canvas } = await import("html2canvas-pro");
594
+ const canvas = await html2canvas(document.body, {
595
+ scale: 0.5,
596
+ logging: false,
597
+ useCORS: true,
598
+ allowTaint: true
599
+ });
600
+ setScreenshot(canvas.toDataURL("image/jpeg", 0.6));
547
601
  } catch (e) {
548
602
  }
549
- }, [isOpen]);
603
+ setCapturing(false);
604
+ setIsOpen(true);
605
+ };
606
+ useEffect2(() => {
607
+ if (!isOpen) return;
608
+ const handleEsc = (e) => {
609
+ if (e.key === "Escape") {
610
+ if (previewOpen) setPreviewOpen(false);
611
+ else setIsOpen(false);
612
+ }
613
+ };
614
+ document.addEventListener("keydown", handleEsc);
615
+ return () => document.removeEventListener("keydown", handleEsc);
616
+ }, [isOpen, previewOpen]);
550
617
  const handleSubmit = () => {
551
618
  try {
552
619
  if (!description.trim() || isSubmitting) return;
553
620
  setIsSubmitting(true);
554
- reportBug(description.trim());
621
+ reportBug(description.trim(), screenshot ? { screenshot } : void 0);
555
622
  setSubmitted(true);
556
623
  setDescription("");
624
+ setScreenshot(null);
557
625
  setIsSubmitting(false);
558
626
  setTimeout(() => {
559
627
  setSubmitted(false);
@@ -563,206 +631,386 @@ function ReportButton({
563
631
  setIsSubmitting(false);
564
632
  }
565
633
  };
566
- const positionStyles = position === "bottom-left" ? { left: "16px", bottom: "16px" } : { right: "16px", bottom: "16px" };
567
- const modalPositionStyles = position === "bottom-left" ? { left: "16px", bottom: "64px" } : { right: "16px", bottom: "64px" };
634
+ const isTop = (_a = position == null ? void 0 : position.startsWith("top")) != null ? _a : false;
635
+ const isLeft = (_b = position == null ? void 0 : position.endsWith("left")) != null ? _b : false;
636
+ const modalPositionStyles = children ? {} : {
637
+ ...isLeft ? { left: "16px" } : { right: "16px" },
638
+ ...isTop ? { top: "64px" } : { bottom: "64px" }
639
+ };
568
640
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
569
- /* @__PURE__ */ jsxs(
570
- "button",
641
+ children ? children({ onClick: handleOpen, capturing }) : /* @__PURE__ */ jsx2(
642
+ DefaultTrigger,
571
643
  {
572
- type: "button",
573
- onClick: () => {
574
- setIsOpen(!isOpen);
575
- setSubmitted(false);
576
- },
644
+ onClick: handleOpen,
645
+ capturing,
646
+ label,
577
647
  className,
648
+ position,
649
+ isLeft,
650
+ isTop
651
+ }
652
+ ),
653
+ isOpen && /* @__PURE__ */ jsx2(
654
+ "div",
655
+ {
578
656
  style: {
579
657
  position: "fixed",
580
- ...positionStyles,
658
+ inset: 0,
581
659
  zIndex: 99999,
582
- padding: "10px 18px",
583
- borderRadius: "24px",
584
- border: "none",
585
- backgroundColor: "#18181b",
586
- color: "#fafafa",
587
- fontSize: "14px",
588
- fontWeight: 500,
589
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
590
- cursor: "pointer",
591
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)",
592
- transition: "transform 0.15s ease, box-shadow 0.15s ease",
593
660
  display: "flex",
594
661
  alignItems: "center",
595
- gap: "6px"
596
- },
597
- onMouseEnter: (e) => {
598
- e.target.style.transform = "scale(1.05)";
662
+ justifyContent: "center",
663
+ backgroundColor: "rgba(0,0,0,0.5)"
599
664
  },
600
- onMouseLeave: (e) => {
601
- e.target.style.transform = "scale(1)";
665
+ onClick: () => {
666
+ if (!previewOpen) setIsOpen(false);
602
667
  },
603
- "aria-label": label,
604
- children: [
605
- /* @__PURE__ */ jsx2(
606
- "svg",
607
- {
608
- width: "16",
609
- height: "16",
610
- viewBox: "0 0 16 16",
611
- fill: "none",
612
- style: { flexShrink: 0 },
613
- children: /* @__PURE__ */ jsx2(
614
- "path",
668
+ children: /* @__PURE__ */ jsxs(
669
+ "div",
670
+ {
671
+ ref: modalRef,
672
+ onClick: (e) => e.stopPropagation(),
673
+ style: {
674
+ position: children ? "relative" : "fixed",
675
+ ...modalPositionStyles,
676
+ zIndex: 1e5,
677
+ width: "340px",
678
+ maxWidth: "calc(100% - 32px)",
679
+ backgroundColor: "#1c1c1e",
680
+ borderRadius: "12px",
681
+ boxShadow: "0 20px 60px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3)",
682
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
683
+ overflow: "hidden",
684
+ color: "#fafafa"
685
+ },
686
+ children: [
687
+ /* @__PURE__ */ jsx2(
688
+ "div",
615
689
  {
616
- d: "M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z",
617
- fill: "currentColor"
690
+ style: {
691
+ padding: "16px 16px 12px",
692
+ borderBottom: "1px solid #2c2c2e"
693
+ },
694
+ children: /* @__PURE__ */ jsxs(
695
+ "div",
696
+ {
697
+ style: {
698
+ display: "flex",
699
+ justifyContent: "space-between",
700
+ alignItems: "center"
701
+ },
702
+ children: [
703
+ /* @__PURE__ */ jsx2(
704
+ "span",
705
+ {
706
+ style: {
707
+ fontSize: "15px",
708
+ fontWeight: 600,
709
+ color: "#fafafa"
710
+ },
711
+ children: "Report a Bug"
712
+ }
713
+ ),
714
+ /* @__PURE__ */ jsx2(
715
+ "button",
716
+ {
717
+ type: "button",
718
+ onClick: () => setIsOpen(false),
719
+ style: {
720
+ background: "none",
721
+ border: "none",
722
+ cursor: "pointer",
723
+ padding: "4px",
724
+ color: "#a1a1aa",
725
+ fontSize: "18px",
726
+ lineHeight: 1
727
+ },
728
+ "aria-label": "Close",
729
+ children: "\xD7"
730
+ }
731
+ )
732
+ ]
733
+ }
734
+ )
735
+ }
736
+ ),
737
+ /* @__PURE__ */ jsx2("div", { style: { padding: "16px" }, children: submitted ? /* @__PURE__ */ jsx2(
738
+ "div",
739
+ {
740
+ style: {
741
+ textAlign: "center",
742
+ padding: "20px 0",
743
+ color: "#22d3ee",
744
+ fontSize: "14px",
745
+ fontWeight: 500
746
+ },
747
+ children: "Bug report sent. Thank you!"
748
+ }
749
+ ) : /* @__PURE__ */ jsxs(Fragment2, { children: [
750
+ screenshot && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "10px", position: "relative" }, children: [
751
+ /* @__PURE__ */ jsx2(
752
+ "img",
753
+ {
754
+ src: screenshot,
755
+ alt: "Page screenshot",
756
+ onClick: () => setPreviewOpen(true),
757
+ style: {
758
+ width: "100%",
759
+ borderRadius: "6px",
760
+ border: "1px solid #2c2c2e",
761
+ maxHeight: "120px",
762
+ objectFit: "cover",
763
+ objectPosition: "top",
764
+ cursor: "pointer"
765
+ }
766
+ }
767
+ ),
768
+ /* @__PURE__ */ jsx2(
769
+ "button",
770
+ {
771
+ type: "button",
772
+ onClick: () => setScreenshot(null),
773
+ style: {
774
+ position: "absolute",
775
+ top: "4px",
776
+ right: "4px",
777
+ background: "rgba(0,0,0,0.6)",
778
+ border: "none",
779
+ borderRadius: "50%",
780
+ color: "#fff",
781
+ width: "20px",
782
+ height: "20px",
783
+ fontSize: "12px",
784
+ cursor: "pointer",
785
+ display: "flex",
786
+ alignItems: "center",
787
+ justifyContent: "center",
788
+ lineHeight: 1
789
+ },
790
+ "aria-label": "Remove screenshot",
791
+ children: "\xD7"
792
+ }
793
+ ),
794
+ /* @__PURE__ */ jsxs(
795
+ "div",
796
+ {
797
+ style: {
798
+ position: "absolute",
799
+ bottom: "4px",
800
+ left: "6px",
801
+ right: "6px",
802
+ display: "flex",
803
+ justifyContent: "space-between",
804
+ alignItems: "center"
805
+ },
806
+ children: [
807
+ /* @__PURE__ */ jsxs(
808
+ "span",
809
+ {
810
+ style: {
811
+ background: "rgba(0,0,0,0.6)",
812
+ color: "#fff",
813
+ fontSize: "10px",
814
+ padding: "2px 6px",
815
+ borderRadius: "4px"
816
+ },
817
+ children: [
818
+ "Screenshot (",
819
+ Math.round(screenshot.length * 0.75 / 1024),
820
+ "KB) \u2014 click to preview"
821
+ ]
822
+ }
823
+ ),
824
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "4px" }, children: [
825
+ /* @__PURE__ */ jsx2(
826
+ "button",
827
+ {
828
+ type: "button",
829
+ onClick: () => {
830
+ var _a2;
831
+ return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
832
+ },
833
+ style: {
834
+ background: "rgba(0,0,0,0.6)",
835
+ color: "#22d3ee",
836
+ fontSize: "10px",
837
+ padding: "2px 6px",
838
+ borderRadius: "4px",
839
+ border: "none",
840
+ cursor: "pointer"
841
+ },
842
+ children: "Upload"
843
+ }
844
+ ),
845
+ /* @__PURE__ */ jsx2(
846
+ "button",
847
+ {
848
+ type: "button",
849
+ onClick: retakeScreenshot,
850
+ style: {
851
+ background: "rgba(0,0,0,0.6)",
852
+ color: "#22d3ee",
853
+ fontSize: "10px",
854
+ padding: "2px 6px",
855
+ borderRadius: "4px",
856
+ border: "none",
857
+ cursor: "pointer"
858
+ },
859
+ children: "Retake"
860
+ }
861
+ )
862
+ ] })
863
+ ]
864
+ }
865
+ )
866
+ ] }),
867
+ !screenshot && !submitted && /* @__PURE__ */ jsx2(
868
+ "button",
869
+ {
870
+ type: "button",
871
+ onClick: () => {
872
+ var _a2;
873
+ return (_a2 = fileInputRef.current) == null ? void 0 : _a2.click();
874
+ },
875
+ style: {
876
+ marginBottom: "10px",
877
+ padding: "10px",
878
+ borderRadius: "6px",
879
+ border: "1px dashed #3f3f46",
880
+ textAlign: "center",
881
+ fontSize: "11px",
882
+ color: "#71717a",
883
+ width: "100%",
884
+ background: "none",
885
+ cursor: "pointer"
886
+ },
887
+ children: "Click to upload a screenshot"
888
+ }
889
+ ),
890
+ /* @__PURE__ */ jsx2(
891
+ "textarea",
892
+ {
893
+ value: description,
894
+ onChange: (e) => setDescription(e.target.value),
895
+ placeholder: "Describe what went wrong...",
896
+ style: {
897
+ width: "100%",
898
+ minHeight: "100px",
899
+ padding: "10px 12px",
900
+ borderRadius: "8px",
901
+ border: "1px solid #3f3f46",
902
+ fontSize: "14px",
903
+ fontFamily: "inherit",
904
+ resize: "vertical",
905
+ outline: "none",
906
+ boxSizing: "border-box",
907
+ color: "#fafafa",
908
+ backgroundColor: "#27272a"
909
+ },
910
+ onFocus: (e) => {
911
+ e.target.style.borderColor = "#22d3ee";
912
+ },
913
+ onBlur: (e) => {
914
+ e.target.style.borderColor = "#3f3f46";
915
+ },
916
+ autoFocus: true
917
+ }
918
+ ),
919
+ /* @__PURE__ */ jsx2(
920
+ "button",
921
+ {
922
+ type: "button",
923
+ onClick: handleSubmit,
924
+ disabled: !description.trim() || isSubmitting,
925
+ style: {
926
+ marginTop: "12px",
927
+ width: "100%",
928
+ padding: "10px",
929
+ borderRadius: "8px",
930
+ border: "none",
931
+ backgroundColor: !description.trim() || isSubmitting ? "#3f3f46" : "#22d3ee",
932
+ color: !description.trim() || isSubmitting ? "#71717a" : "#09090b",
933
+ fontSize: "14px",
934
+ fontWeight: 600,
935
+ cursor: !description.trim() || isSubmitting ? "not-allowed" : "pointer",
936
+ fontFamily: "inherit",
937
+ transition: "background-color 0.15s ease"
938
+ },
939
+ children: isSubmitting ? "Sending..." : "Send Report"
940
+ }
941
+ )
942
+ ] }) }),
943
+ /* @__PURE__ */ jsx2(
944
+ "div",
945
+ {
946
+ style: {
947
+ padding: "8px 16px 10px",
948
+ borderTop: "1px solid #2c2c2e",
949
+ textAlign: "center"
950
+ },
951
+ children: /* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", color: "#52525b" }, children: "Powered by Glitchgrab" })
618
952
  }
619
953
  )
620
- }
621
- ),
622
- label
623
- ]
954
+ ]
955
+ }
956
+ )
957
+ }
958
+ ),
959
+ /* @__PURE__ */ jsx2(
960
+ "input",
961
+ {
962
+ ref: fileInputRef,
963
+ type: "file",
964
+ accept: "image/*",
965
+ onChange: handleFileUpload,
966
+ style: { display: "none" }
624
967
  }
625
968
  ),
626
- isOpen && /* @__PURE__ */ jsxs(
969
+ previewOpen && screenshot && /* @__PURE__ */ jsxs(
627
970
  "div",
628
971
  {
629
- ref: modalRef,
630
972
  style: {
631
973
  position: "fixed",
632
- ...modalPositionStyles,
633
- zIndex: 1e5,
634
- width: "320px",
635
- backgroundColor: "#ffffff",
636
- borderRadius: "12px",
637
- boxShadow: "0 20px 60px rgba(0, 0, 0, 0.15), 0 4px 16px rgba(0, 0, 0, 0.1)",
638
- fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
639
- overflow: "hidden"
974
+ inset: 0,
975
+ zIndex: 2e5,
976
+ backgroundColor: "rgba(0,0,0,0.85)",
977
+ display: "flex",
978
+ flexDirection: "column",
979
+ alignItems: "center",
980
+ justifyContent: "center",
981
+ padding: "16px",
982
+ cursor: "pointer"
983
+ },
984
+ onClick: (e) => {
985
+ e.stopPropagation();
986
+ setPreviewOpen(false);
640
987
  },
988
+ onMouseDown: (e) => e.stopPropagation(),
641
989
  children: [
642
990
  /* @__PURE__ */ jsx2(
643
- "div",
991
+ "img",
644
992
  {
993
+ src: screenshot,
994
+ alt: "Screenshot preview",
995
+ onClick: (e) => e.stopPropagation(),
645
996
  style: {
646
- padding: "16px 16px 12px",
647
- borderBottom: "1px solid #e4e4e7"
648
- },
649
- children: /* @__PURE__ */ jsxs(
650
- "div",
651
- {
652
- style: {
653
- display: "flex",
654
- justifyContent: "space-between",
655
- alignItems: "center"
656
- },
657
- children: [
658
- /* @__PURE__ */ jsx2(
659
- "span",
660
- {
661
- style: {
662
- fontSize: "15px",
663
- fontWeight: 600,
664
- color: "#18181b"
665
- },
666
- children: "Report a Bug"
667
- }
668
- ),
669
- /* @__PURE__ */ jsx2(
670
- "button",
671
- {
672
- type: "button",
673
- onClick: () => setIsOpen(false),
674
- style: {
675
- background: "none",
676
- border: "none",
677
- cursor: "pointer",
678
- padding: "4px",
679
- color: "#71717a",
680
- fontSize: "18px",
681
- lineHeight: 1
682
- },
683
- "aria-label": "Close",
684
- children: "\xD7"
685
- }
686
- )
687
- ]
688
- }
689
- )
997
+ maxWidth: "100%",
998
+ maxHeight: "calc(100vh - 80px)",
999
+ borderRadius: "8px",
1000
+ objectFit: "contain",
1001
+ cursor: "default"
1002
+ }
690
1003
  }
691
1004
  ),
692
- /* @__PURE__ */ jsx2("div", { style: { padding: "16px" }, children: submitted ? /* @__PURE__ */ jsx2(
693
- "div",
694
- {
695
- style: {
696
- textAlign: "center",
697
- padding: "20px 0",
698
- color: "#16a34a",
699
- fontSize: "14px",
700
- fontWeight: 500
701
- },
702
- children: "Bug report sent. Thank you!"
703
- }
704
- ) : /* @__PURE__ */ jsxs(Fragment2, { children: [
705
- /* @__PURE__ */ jsx2(
706
- "textarea",
707
- {
708
- value: description,
709
- onChange: (e) => setDescription(e.target.value),
710
- placeholder: "Describe what went wrong...",
711
- style: {
712
- width: "100%",
713
- minHeight: "100px",
714
- padding: "10px 12px",
715
- borderRadius: "8px",
716
- border: "1px solid #d4d4d8",
717
- fontSize: "14px",
718
- fontFamily: "inherit",
719
- resize: "vertical",
720
- outline: "none",
721
- boxSizing: "border-box",
722
- color: "#18181b",
723
- backgroundColor: "#fafafa"
724
- },
725
- onFocus: (e) => {
726
- e.target.style.borderColor = "#18181b";
727
- },
728
- onBlur: (e) => {
729
- e.target.style.borderColor = "#d4d4d8";
730
- }
731
- }
732
- ),
733
- /* @__PURE__ */ jsx2(
734
- "button",
735
- {
736
- type: "button",
737
- onClick: handleSubmit,
738
- disabled: !description.trim() || isSubmitting,
739
- style: {
740
- marginTop: "12px",
741
- width: "100%",
742
- padding: "10px",
743
- borderRadius: "8px",
744
- border: "none",
745
- backgroundColor: !description.trim() || isSubmitting ? "#a1a1aa" : "#18181b",
746
- color: "#fafafa",
747
- fontSize: "14px",
748
- fontWeight: 500,
749
- cursor: !description.trim() || isSubmitting ? "not-allowed" : "pointer",
750
- fontFamily: "inherit",
751
- transition: "background-color 0.15s ease"
752
- },
753
- children: isSubmitting ? "Sending..." : "Send Report"
754
- }
755
- )
756
- ] }) }),
757
1005
  /* @__PURE__ */ jsx2(
758
- "div",
1006
+ "span",
759
1007
  {
760
1008
  style: {
761
- padding: "8px 16px 10px",
762
- borderTop: "1px solid #e4e4e7",
763
- textAlign: "center"
1009
+ marginTop: "12px",
1010
+ color: "#a1a1aa",
1011
+ fontSize: "12px"
764
1012
  },
765
- children: /* @__PURE__ */ jsx2("span", { style: { fontSize: "11px", color: "#a1a1aa" }, children: "Powered by Glitchgrab" })
1013
+ children: "Click outside to close"
766
1014
  }
767
1015
  )
768
1016
  ]
@@ -770,6 +1018,76 @@ function ReportButton({
770
1018
  )
771
1019
  ] });
772
1020
  }
1021
+ function DefaultTrigger({
1022
+ onClick,
1023
+ capturing,
1024
+ label,
1025
+ className,
1026
+ position,
1027
+ isLeft,
1028
+ isTop
1029
+ }) {
1030
+ const positionStyles = {
1031
+ ...isLeft ? { left: "16px" } : { right: "16px" },
1032
+ ...isTop ? { top: "16px" } : { bottom: "16px" }
1033
+ };
1034
+ return /* @__PURE__ */ jsxs(
1035
+ "button",
1036
+ {
1037
+ type: "button",
1038
+ onClick,
1039
+ disabled: capturing,
1040
+ className,
1041
+ style: {
1042
+ position: "fixed",
1043
+ ...positionStyles,
1044
+ zIndex: 99999,
1045
+ padding: "10px 18px",
1046
+ borderRadius: "24px",
1047
+ border: "none",
1048
+ backgroundColor: "#18181b",
1049
+ color: "#fafafa",
1050
+ fontSize: "14px",
1051
+ fontWeight: 500,
1052
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
1053
+ cursor: capturing ? "wait" : "pointer",
1054
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.1)",
1055
+ transition: "transform 0.15s ease, box-shadow 0.15s ease",
1056
+ display: "flex",
1057
+ alignItems: "center",
1058
+ gap: "6px",
1059
+ opacity: capturing ? 0.7 : 1
1060
+ },
1061
+ onMouseEnter: (e) => {
1062
+ e.target.style.transform = "scale(1.05)";
1063
+ },
1064
+ onMouseLeave: (e) => {
1065
+ e.target.style.transform = "scale(1)";
1066
+ },
1067
+ "aria-label": label,
1068
+ children: [
1069
+ /* @__PURE__ */ jsx2(
1070
+ "svg",
1071
+ {
1072
+ width: "16",
1073
+ height: "16",
1074
+ viewBox: "0 0 16 16",
1075
+ fill: "none",
1076
+ style: { flexShrink: 0 },
1077
+ children: /* @__PURE__ */ jsx2(
1078
+ "path",
1079
+ {
1080
+ d: "M8 1C4.134 1 1 4.134 1 8s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm0 12.5a.75.75 0 110-1.5.75.75 0 010 1.5zm.75-3.5a.75.75 0 01-1.5 0V5a.75.75 0 011.5 0v5z",
1081
+ fill: "currentColor"
1082
+ }
1083
+ )
1084
+ }
1085
+ ),
1086
+ capturing ? "Capturing..." : label
1087
+ ]
1088
+ }
1089
+ );
1090
+ }
773
1091
  export {
774
1092
  GlitchgrabErrorBoundary,
775
1093
  GlitchgrabProvider,