@outcode/bug-reporter-web 0.1.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/LICENSE +21 -0
- package/README.md +75 -0
- package/dist/index.d.mts +136 -0
- package/dist/index.d.ts +136 -0
- package/dist/index.js +1274 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1258 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OutCode Software
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @outcode/bug-reporter-web
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@outcode/bug-reporter-web)
|
|
4
|
+
[](https://www.npmjs.com/package/@outcode/bug-reporter-web)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
|
|
8
|
+
**In-app bug reporter for React (web).** Drop in a floating button — your users capture the current
|
|
9
|
+
screen, annotate it (draw, arrow, box, blur, text), set a severity and type, and file a report to
|
|
10
|
+
**ClickUp** or any custom backend. No backend code required to get started.
|
|
11
|
+
|
|
12
|
+
> Part of the [OutCode Bug Reporter](https://github.com/OutCode-Software/bug-reporter) monorepo.
|
|
13
|
+
> For React Native, see [`@outcode/bug-reporter-native`](https://www.npmjs.com/package/@outcode/bug-reporter-native).
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- 🎯 **One component** — `<BugReporterButton />` runs the whole capture → annotate → form → done flow
|
|
18
|
+
- ✏️ **Annotate** — pen, arrow, box, **blur/redact**, and text, flattened onto the screenshot
|
|
19
|
+
- 🧭 **Auto-captured context** — route, browser, viewport, language, connection type, console errors… all consent-free
|
|
20
|
+
- 🎨 **Themeable** — Indigo / Noir / Mint presets or your own tokens
|
|
21
|
+
- 📡 **Offline retry queue**, **log/breadcrumb capture**, screenshot **size guard**
|
|
22
|
+
- 🧩 **Pluggable backends** — ClickUp out of the box, or any `repository` / HTTP endpoint
|
|
23
|
+
- 📦 Tree-shakeable ESM + CJS, fully typed
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @outcode/bug-reporter-web @outcode/bug-reporter-core
|
|
29
|
+
# peers:
|
|
30
|
+
npm install react react-dom
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`html2canvas` is bundled — no extra install needed.
|
|
34
|
+
|
|
35
|
+
## Quick start
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { BugReporterButton } from '@outcode/bug-reporter-web';
|
|
39
|
+
import { ClickUpBugReporterRepository } from '@outcode/bug-reporter-core';
|
|
40
|
+
|
|
41
|
+
export function App() {
|
|
42
|
+
return (
|
|
43
|
+
<>
|
|
44
|
+
{/* …your app… */}
|
|
45
|
+
<BugReporterButton
|
|
46
|
+
config={{
|
|
47
|
+
appName: 'My Web App',
|
|
48
|
+
appVersion: '1.0.0',
|
|
49
|
+
theme: 'indigo',
|
|
50
|
+
repository: new ClickUpBugReporterRepository({
|
|
51
|
+
apiKey: import.meta.env.VITE_CLICKUP_API_KEY,
|
|
52
|
+
problemListId: import.meta.env.VITE_CLICKUP_PROBLEM_LIST_ID,
|
|
53
|
+
suggestionListId: import.meta.env.VITE_CLICKUP_SUGGESTION_LIST_ID,
|
|
54
|
+
}),
|
|
55
|
+
}}
|
|
56
|
+
/>
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
No ClickUp? Use the default HTTP backend instead: `config={{ appName, apiUrl: 'https://your-api/bug-report' }}`.
|
|
63
|
+
|
|
64
|
+
> ⚠️ Don't ship a ClickUp API key in a public web bundle. Prefer the `apiUrl` path behind a server
|
|
65
|
+
> proxy that holds the key; reserve direct-to-ClickUp for internal/trusted builds.
|
|
66
|
+
|
|
67
|
+
## Configuration
|
|
68
|
+
|
|
69
|
+
Full `BugReporterConfig` reference (theme, `screenshot` size guard, offline `storage`, `collectContext`,
|
|
70
|
+
`collectDiagnostics`, `backendName`, …) lives in the
|
|
71
|
+
[root README](https://github.com/OutCode-Software/bug-reporter#readme).
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT © OutCode Software
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BugReporterConfig, AnnotationTool, ReportSeverity, ReportType, ScreenshotOptions, Annotation, ReportQueueStorage, BugReporterTheme } from '@outcode/bug-reporter-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bug reporter (web) — floating button + full capture→annotate→form→done flow,
|
|
6
|
+
* matching the OC-BugReporter design. Orchestrates the step state machine and
|
|
7
|
+
* hosts the themed overlays (annotate editor, slide-in form, success card).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface BugReporterButtonProps {
|
|
11
|
+
config: BugReporterConfig;
|
|
12
|
+
/** Accessible label for the floating button. */
|
|
13
|
+
label?: string;
|
|
14
|
+
/** Override styles for the floating button. */
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
}
|
|
17
|
+
declare function BugReporterButton({ config, label, style }: BugReporterButtonProps): React.JSX.Element;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Full-screen annotation editor (web) — ported from the OC-BugReporter design.
|
|
21
|
+
* Tools: pen, arrow, box, blur, text. Renders the captured screenshot fitted to
|
|
22
|
+
* the viewport with a live SVG/visual overlay and the AnnotateToolbar on top.
|
|
23
|
+
* On Continue, flattens annotations into a single PNG.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
interface AnnotateOverlayProps {
|
|
27
|
+
src: string;
|
|
28
|
+
onCancel: () => void;
|
|
29
|
+
/** Called with the flattened screenshot data URL and the annotation count. */
|
|
30
|
+
onContinue: (flattenedDataUrl: string, annotationCount: number) => void;
|
|
31
|
+
}
|
|
32
|
+
declare function AnnotateOverlay({ src, onCancel, onContinue }: AnnotateOverlayProps): React.JSX.Element;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Annotation toolbar (web) — tools, color palette, undo/clear, Continue.
|
|
36
|
+
* Ported from the OC-BugReporter AnnotateToolbar design. Uses CSS vars from the
|
|
37
|
+
* reporter root for theming.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
interface AnnotateToolbarProps {
|
|
41
|
+
tool: AnnotationTool;
|
|
42
|
+
color: string;
|
|
43
|
+
onTool: (t: AnnotationTool) => void;
|
|
44
|
+
onColor: (c: string) => void;
|
|
45
|
+
onUndo: () => void;
|
|
46
|
+
onClear: () => void;
|
|
47
|
+
onContinue: () => void;
|
|
48
|
+
}
|
|
49
|
+
declare function AnnotateToolbar({ tool, color, onTool, onColor, onUndo, onClear, onContinue, }: AnnotateToolbarProps): React.JSX.Element;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Bug report form (web) — ported from the OC-BugReporter BugReportForm design.
|
|
53
|
+
* Summary, description, severity, type, collapsible auto-captured context, and a
|
|
54
|
+
* "Filing to …" footer. Rendered as a right slide-in panel by the orchestrator.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
interface MetaRow {
|
|
58
|
+
label: string;
|
|
59
|
+
value: string;
|
|
60
|
+
flag?: 'err' | 'warn';
|
|
61
|
+
}
|
|
62
|
+
interface BugReportFormProps {
|
|
63
|
+
screenshotUrl?: string;
|
|
64
|
+
annotationCount: number;
|
|
65
|
+
title: string;
|
|
66
|
+
description: string;
|
|
67
|
+
severity: ReportSeverity;
|
|
68
|
+
type: ReportType;
|
|
69
|
+
meta: MetaRow[];
|
|
70
|
+
backendName: string;
|
|
71
|
+
submitting: boolean;
|
|
72
|
+
error?: string;
|
|
73
|
+
onTitle: (v: string) => void;
|
|
74
|
+
onDescription: (v: string) => void;
|
|
75
|
+
onSeverity: (s: ReportSeverity) => void;
|
|
76
|
+
onType: (t: ReportType) => void;
|
|
77
|
+
onBack: () => void;
|
|
78
|
+
onClose: () => void;
|
|
79
|
+
onEditAnnotations: () => void;
|
|
80
|
+
onSubmit: () => void;
|
|
81
|
+
}
|
|
82
|
+
declare function BugReportForm(props: BugReportFormProps): React.JSX.Element;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Success card (web) — ported from the OC-BugReporter "Report filed" state.
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
interface SuccessCardProps {
|
|
89
|
+
ticket?: string;
|
|
90
|
+
ticketTitle: string;
|
|
91
|
+
backendName: string;
|
|
92
|
+
onDone: () => void;
|
|
93
|
+
}
|
|
94
|
+
declare function SuccessCard({ ticket, ticketTitle, backendName, onDone }: SuccessCardProps): React.JSX.Element;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Captures the current viewport (visible screen) as a PNG/JPEG data URL.
|
|
98
|
+
* Uses html2canvas; runs in browser only. Applies an optional size guard
|
|
99
|
+
* (maxWidth downscale + format/quality) so large/retina screens don't produce
|
|
100
|
+
* multi-megabyte uploads.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Capture the visible viewport as a data URL (for display and for API base64).
|
|
105
|
+
*/
|
|
106
|
+
declare function captureViewport(options?: ScreenshotOptions): Promise<string | undefined>;
|
|
107
|
+
/** Strip data URL prefix to get raw base64 for API. */
|
|
108
|
+
declare function dataUrlToBase64(dataUrl: string): string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Composite annotations onto the screenshot, producing a single PNG data URL.
|
|
112
|
+
* Shapes are stored in display (stage) pixels; we scale them to the image's
|
|
113
|
+
* natural pixel size so the exported image is full resolution.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
declare function flattenAnnotations(src: string, shapes: Annotation[], dispW: number, dispH: number): Promise<string>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Default web storage adapter for the offline retry queue, backed by localStorage.
|
|
120
|
+
* Returns undefined in non-browser / storage-disabled environments (SSR, private
|
|
121
|
+
* mode with blocked storage), so callers can treat the queue as unavailable.
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
declare function getDefaultWebStorage(): ReportQueueStorage | undefined;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Web theme helpers — turn resolved theme tokens into CSS custom properties so
|
|
128
|
+
* the design's `var(--accent)` style strings work verbatim, and shared font stacks.
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/** CSS custom properties for a theme, to spread onto the reporter root element. */
|
|
132
|
+
declare function cssVars(t: BugReporterTheme): Record<string, string>;
|
|
133
|
+
/** Inject the reporter keyframes once. Safe no-op on the server. */
|
|
134
|
+
declare function ensureKeyframes(): void;
|
|
135
|
+
|
|
136
|
+
export { AnnotateOverlay, type AnnotateOverlayProps, AnnotateToolbar, BugReportForm, type BugReportFormProps, BugReporterButton, type BugReporterButtonProps, type MetaRow, SuccessCard, captureViewport, cssVars, dataUrlToBase64, ensureKeyframes, flattenAnnotations, getDefaultWebStorage };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BugReporterConfig, AnnotationTool, ReportSeverity, ReportType, ScreenshotOptions, Annotation, ReportQueueStorage, BugReporterTheme } from '@outcode/bug-reporter-core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bug reporter (web) — floating button + full capture→annotate→form→done flow,
|
|
6
|
+
* matching the OC-BugReporter design. Orchestrates the step state machine and
|
|
7
|
+
* hosts the themed overlays (annotate editor, slide-in form, success card).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface BugReporterButtonProps {
|
|
11
|
+
config: BugReporterConfig;
|
|
12
|
+
/** Accessible label for the floating button. */
|
|
13
|
+
label?: string;
|
|
14
|
+
/** Override styles for the floating button. */
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
}
|
|
17
|
+
declare function BugReporterButton({ config, label, style }: BugReporterButtonProps): React.JSX.Element;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Full-screen annotation editor (web) — ported from the OC-BugReporter design.
|
|
21
|
+
* Tools: pen, arrow, box, blur, text. Renders the captured screenshot fitted to
|
|
22
|
+
* the viewport with a live SVG/visual overlay and the AnnotateToolbar on top.
|
|
23
|
+
* On Continue, flattens annotations into a single PNG.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
interface AnnotateOverlayProps {
|
|
27
|
+
src: string;
|
|
28
|
+
onCancel: () => void;
|
|
29
|
+
/** Called with the flattened screenshot data URL and the annotation count. */
|
|
30
|
+
onContinue: (flattenedDataUrl: string, annotationCount: number) => void;
|
|
31
|
+
}
|
|
32
|
+
declare function AnnotateOverlay({ src, onCancel, onContinue }: AnnotateOverlayProps): React.JSX.Element;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Annotation toolbar (web) — tools, color palette, undo/clear, Continue.
|
|
36
|
+
* Ported from the OC-BugReporter AnnotateToolbar design. Uses CSS vars from the
|
|
37
|
+
* reporter root for theming.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
interface AnnotateToolbarProps {
|
|
41
|
+
tool: AnnotationTool;
|
|
42
|
+
color: string;
|
|
43
|
+
onTool: (t: AnnotationTool) => void;
|
|
44
|
+
onColor: (c: string) => void;
|
|
45
|
+
onUndo: () => void;
|
|
46
|
+
onClear: () => void;
|
|
47
|
+
onContinue: () => void;
|
|
48
|
+
}
|
|
49
|
+
declare function AnnotateToolbar({ tool, color, onTool, onColor, onUndo, onClear, onContinue, }: AnnotateToolbarProps): React.JSX.Element;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Bug report form (web) — ported from the OC-BugReporter BugReportForm design.
|
|
53
|
+
* Summary, description, severity, type, collapsible auto-captured context, and a
|
|
54
|
+
* "Filing to …" footer. Rendered as a right slide-in panel by the orchestrator.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
interface MetaRow {
|
|
58
|
+
label: string;
|
|
59
|
+
value: string;
|
|
60
|
+
flag?: 'err' | 'warn';
|
|
61
|
+
}
|
|
62
|
+
interface BugReportFormProps {
|
|
63
|
+
screenshotUrl?: string;
|
|
64
|
+
annotationCount: number;
|
|
65
|
+
title: string;
|
|
66
|
+
description: string;
|
|
67
|
+
severity: ReportSeverity;
|
|
68
|
+
type: ReportType;
|
|
69
|
+
meta: MetaRow[];
|
|
70
|
+
backendName: string;
|
|
71
|
+
submitting: boolean;
|
|
72
|
+
error?: string;
|
|
73
|
+
onTitle: (v: string) => void;
|
|
74
|
+
onDescription: (v: string) => void;
|
|
75
|
+
onSeverity: (s: ReportSeverity) => void;
|
|
76
|
+
onType: (t: ReportType) => void;
|
|
77
|
+
onBack: () => void;
|
|
78
|
+
onClose: () => void;
|
|
79
|
+
onEditAnnotations: () => void;
|
|
80
|
+
onSubmit: () => void;
|
|
81
|
+
}
|
|
82
|
+
declare function BugReportForm(props: BugReportFormProps): React.JSX.Element;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Success card (web) — ported from the OC-BugReporter "Report filed" state.
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
interface SuccessCardProps {
|
|
89
|
+
ticket?: string;
|
|
90
|
+
ticketTitle: string;
|
|
91
|
+
backendName: string;
|
|
92
|
+
onDone: () => void;
|
|
93
|
+
}
|
|
94
|
+
declare function SuccessCard({ ticket, ticketTitle, backendName, onDone }: SuccessCardProps): React.JSX.Element;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Captures the current viewport (visible screen) as a PNG/JPEG data URL.
|
|
98
|
+
* Uses html2canvas; runs in browser only. Applies an optional size guard
|
|
99
|
+
* (maxWidth downscale + format/quality) so large/retina screens don't produce
|
|
100
|
+
* multi-megabyte uploads.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Capture the visible viewport as a data URL (for display and for API base64).
|
|
105
|
+
*/
|
|
106
|
+
declare function captureViewport(options?: ScreenshotOptions): Promise<string | undefined>;
|
|
107
|
+
/** Strip data URL prefix to get raw base64 for API. */
|
|
108
|
+
declare function dataUrlToBase64(dataUrl: string): string;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Composite annotations onto the screenshot, producing a single PNG data URL.
|
|
112
|
+
* Shapes are stored in display (stage) pixels; we scale them to the image's
|
|
113
|
+
* natural pixel size so the exported image is full resolution.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
declare function flattenAnnotations(src: string, shapes: Annotation[], dispW: number, dispH: number): Promise<string>;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Default web storage adapter for the offline retry queue, backed by localStorage.
|
|
120
|
+
* Returns undefined in non-browser / storage-disabled environments (SSR, private
|
|
121
|
+
* mode with blocked storage), so callers can treat the queue as unavailable.
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
declare function getDefaultWebStorage(): ReportQueueStorage | undefined;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Web theme helpers — turn resolved theme tokens into CSS custom properties so
|
|
128
|
+
* the design's `var(--accent)` style strings work verbatim, and shared font stacks.
|
|
129
|
+
*/
|
|
130
|
+
|
|
131
|
+
/** CSS custom properties for a theme, to spread onto the reporter root element. */
|
|
132
|
+
declare function cssVars(t: BugReporterTheme): Record<string, string>;
|
|
133
|
+
/** Inject the reporter keyframes once. Safe no-op on the server. */
|
|
134
|
+
declare function ensureKeyframes(): void;
|
|
135
|
+
|
|
136
|
+
export { AnnotateOverlay, type AnnotateOverlayProps, AnnotateToolbar, BugReportForm, type BugReportFormProps, BugReporterButton, type BugReporterButtonProps, type MetaRow, SuccessCard, captureViewport, cssVars, dataUrlToBase64, ensureKeyframes, flattenAnnotations, getDefaultWebStorage };
|