@bugspotter/sdk 0.2.5-alpha.5 → 0.3.1
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/.prettierrc +11 -0
- package/CHANGELOG.md +81 -149
- package/dist/bugspotter.min.js +1 -1
- package/dist/capture/console.d.ts +1 -0
- package/dist/capture/console.js +17 -4
- package/dist/capture/network.d.ts +6 -0
- package/dist/capture/network.js +12 -2
- package/dist/capture/screenshot.js +3 -2
- package/dist/core/buffer.js +2 -1
- package/dist/core/bug-reporter.js +16 -5
- package/dist/core/circular-buffer.js +4 -1
- package/dist/core/compress.js +2 -1
- package/dist/core/file-upload-handler.js +5 -2
- package/dist/core/offline-queue.js +5 -2
- package/dist/core/transport.js +4 -2
- package/dist/core/upload-helpers.js +3 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.esm.js +16889 -44
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/utils/sanitize-patterns.js +15 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/widget/components/form-validator.js +2 -1
- package/dist/widget/components/style-manager.d.ts +17 -0
- package/dist/widget/components/style-manager.js +318 -108
- package/dist/widget/components/template-manager.js +2 -1
- package/dist/widget/modal.js +11 -4
- package/eslint.config.js +89 -0
- package/package.json +28 -14
- package/rollup.config.js +25 -0
package/dist/index.js
CHANGED
|
@@ -62,7 +62,9 @@ async function fetchReplaySettings(endpoint, apiKey) {
|
|
|
62
62
|
if (apiKey) {
|
|
63
63
|
headers['x-api-key'] = apiKey;
|
|
64
64
|
}
|
|
65
|
-
const response = await fetch(`${apiBaseUrl}/api/v1/settings/replay`, {
|
|
65
|
+
const response = await fetch(`${apiBaseUrl}/api/v1/settings/replay`, {
|
|
66
|
+
headers,
|
|
67
|
+
});
|
|
66
68
|
if (!response.ok) {
|
|
67
69
|
logger.warn(`Failed to fetch replay settings: ${response.status}. Using defaults.`);
|
|
68
70
|
return defaults;
|
|
@@ -20,7 +20,11 @@ exports.DEFAULT_PATTERNS = {
|
|
|
20
20
|
name: 'email',
|
|
21
21
|
regex: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
|
|
22
22
|
description: 'Email addresses',
|
|
23
|
-
examples: [
|
|
23
|
+
examples: [
|
|
24
|
+
'user@example.com',
|
|
25
|
+
'john.doe+tag@company.co.uk',
|
|
26
|
+
'test_user@sub.domain.com',
|
|
27
|
+
],
|
|
24
28
|
priority: 1, // Highest priority - most specific
|
|
25
29
|
},
|
|
26
30
|
creditcard: {
|
|
@@ -53,7 +57,11 @@ exports.DEFAULT_PATTERNS = {
|
|
|
53
57
|
name: 'ip',
|
|
54
58
|
regex: /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/g,
|
|
55
59
|
description: 'IPv4 and IPv6 addresses',
|
|
56
|
-
examples: [
|
|
60
|
+
examples: [
|
|
61
|
+
'192.168.1.100',
|
|
62
|
+
'127.0.0.1',
|
|
63
|
+
'2001:0db8:85a3:0000:0000:8a2e:0370:7334',
|
|
64
|
+
],
|
|
57
65
|
priority: 5,
|
|
58
66
|
},
|
|
59
67
|
phone: {
|
|
@@ -96,7 +104,11 @@ exports.DEFAULT_PATTERNS = {
|
|
|
96
104
|
name: 'password',
|
|
97
105
|
regex: /(?:password|passwd|pwd)[\s:=]+[^\s]{6,}|(?:password|passwd|pwd)["']?\s*[:=]\s*["']?[^\s"']{6,}/gi,
|
|
98
106
|
description: 'Password fields in text (password=..., pwd:...)',
|
|
99
|
-
examples: [
|
|
107
|
+
examples: [
|
|
108
|
+
'password: MySecret123!',
|
|
109
|
+
'passwd=SecurePass456',
|
|
110
|
+
'pwd: "MyP@ssw0rd"',
|
|
111
|
+
],
|
|
100
112
|
priority: 9,
|
|
101
113
|
},
|
|
102
114
|
};
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -31,7 +31,8 @@ class FormValidator {
|
|
|
31
31
|
}
|
|
32
32
|
// Validate PII confirmation if PII detected
|
|
33
33
|
if (data.piiDetected && !data.piiConfirmed) {
|
|
34
|
-
errors.piiConfirmation =
|
|
34
|
+
errors.piiConfirmation =
|
|
35
|
+
'Please confirm you have reviewed sensitive information';
|
|
35
36
|
}
|
|
36
37
|
return {
|
|
37
38
|
isValid: Object.keys(errors).length === 0,
|
|
@@ -13,11 +13,28 @@ export interface StyleConfig {
|
|
|
13
13
|
}
|
|
14
14
|
export declare class StyleManager {
|
|
15
15
|
private config;
|
|
16
|
+
private readonly SPACING;
|
|
17
|
+
private readonly BREAKPOINTS;
|
|
18
|
+
private readonly MODAL_SIZES;
|
|
19
|
+
private readonly FONT_SIZES;
|
|
20
|
+
private readonly BORDER_STYLES;
|
|
21
|
+
private readonly SHADOW_STYLES;
|
|
16
22
|
constructor(config?: StyleConfig);
|
|
17
23
|
/**
|
|
18
24
|
* Generate complete CSS stylesheet for the modal
|
|
19
25
|
*/
|
|
20
26
|
generateStyles(): string;
|
|
27
|
+
private generateOverlayStyles;
|
|
28
|
+
private generateModalStyles;
|
|
29
|
+
private generateHeaderStyles;
|
|
30
|
+
private generateBodyStyles;
|
|
31
|
+
private generateFormStyles;
|
|
32
|
+
private generateButtonStyles;
|
|
33
|
+
private generatePIIStyles;
|
|
34
|
+
private generateLoadingStyles;
|
|
35
|
+
private generateAccessibilityStyles;
|
|
36
|
+
private generateTabletResponsiveStyles;
|
|
37
|
+
private generateMobileResponsiveStyles;
|
|
21
38
|
/**
|
|
22
39
|
* Inject styles into document head
|
|
23
40
|
*/
|
|
@@ -9,11 +9,50 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.StyleManager = void 0;
|
|
10
10
|
class StyleManager {
|
|
11
11
|
constructor(config = {}) {
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// SPACING & SIZING CONSTANTS
|
|
14
|
+
// ============================================================================
|
|
15
|
+
this.SPACING = {
|
|
16
|
+
xs: 8,
|
|
17
|
+
sm: 12,
|
|
18
|
+
md: 16,
|
|
19
|
+
lg: 20,
|
|
20
|
+
};
|
|
21
|
+
this.BREAKPOINTS = {
|
|
22
|
+
tablet: 768,
|
|
23
|
+
mobile: 480,
|
|
24
|
+
};
|
|
25
|
+
this.MODAL_SIZES = {
|
|
26
|
+
desktop: '600px',
|
|
27
|
+
tablet: '500px',
|
|
28
|
+
mobilePercent: '98%',
|
|
29
|
+
headerHeight: '30px',
|
|
30
|
+
};
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// FONT & LAYOUT CONSTANTS
|
|
33
|
+
// ============================================================================
|
|
34
|
+
this.FONT_SIZES = {
|
|
35
|
+
h2: '20px',
|
|
36
|
+
h2Mobile: '18px',
|
|
37
|
+
label: '14px',
|
|
38
|
+
labelMobile: '13px',
|
|
39
|
+
body: '14px',
|
|
40
|
+
small: '12px',
|
|
41
|
+
sr: '13px',
|
|
42
|
+
};
|
|
43
|
+
this.BORDER_STYLES = {
|
|
44
|
+
primary: '1px solid #e0e0e0',
|
|
45
|
+
light: '1px solid #ddd',
|
|
46
|
+
};
|
|
47
|
+
this.SHADOW_STYLES = {
|
|
48
|
+
modal: '0 4px 6px rgba(0, 0, 0, 0.1)',
|
|
49
|
+
};
|
|
12
50
|
this.config = {
|
|
13
51
|
primaryColor: config.primaryColor || '#007bff',
|
|
14
52
|
dangerColor: config.dangerColor || '#dc3545',
|
|
15
53
|
borderRadius: config.borderRadius || '4px',
|
|
16
|
-
fontFamily: config.fontFamily ||
|
|
54
|
+
fontFamily: config.fontFamily ||
|
|
55
|
+
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
17
56
|
zIndex: config.zIndex || 999999,
|
|
18
57
|
};
|
|
19
58
|
}
|
|
@@ -22,6 +61,24 @@ class StyleManager {
|
|
|
22
61
|
*/
|
|
23
62
|
generateStyles() {
|
|
24
63
|
return `
|
|
64
|
+
${this.generateOverlayStyles()}
|
|
65
|
+
${this.generateModalStyles()}
|
|
66
|
+
${this.generateHeaderStyles()}
|
|
67
|
+
${this.generateBodyStyles()}
|
|
68
|
+
${this.generateFormStyles()}
|
|
69
|
+
${this.generateButtonStyles()}
|
|
70
|
+
${this.generatePIIStyles()}
|
|
71
|
+
${this.generateLoadingStyles()}
|
|
72
|
+
${this.generateAccessibilityStyles()}
|
|
73
|
+
${this.generateTabletResponsiveStyles()}
|
|
74
|
+
${this.generateMobileResponsiveStyles()}
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// COMPONENT STYLES - OVERLAY & MODAL
|
|
79
|
+
// ============================================================================
|
|
80
|
+
generateOverlayStyles() {
|
|
81
|
+
return `
|
|
25
82
|
.overlay {
|
|
26
83
|
position: fixed;
|
|
27
84
|
top: 0;
|
|
@@ -35,20 +92,35 @@ class StyleManager {
|
|
|
35
92
|
z-index: ${this.config.zIndex};
|
|
36
93
|
font-family: ${this.config.fontFamily};
|
|
37
94
|
}
|
|
38
|
-
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
generateModalStyles() {
|
|
98
|
+
return `
|
|
39
99
|
.modal {
|
|
40
100
|
background: white;
|
|
41
101
|
border-radius: 8px;
|
|
42
102
|
width: 90%;
|
|
43
|
-
max-width:
|
|
103
|
+
max-width: ${this.MODAL_SIZES.desktop};
|
|
44
104
|
max-height: 90vh;
|
|
45
105
|
overflow-y: auto;
|
|
46
|
-
box-shadow:
|
|
106
|
+
box-shadow: ${this.SHADOW_STYLES.modal};
|
|
107
|
+
scrollbar-width: none;
|
|
108
|
+
-ms-overflow-style: none;
|
|
47
109
|
}
|
|
48
110
|
|
|
111
|
+
.modal::-webkit-scrollbar {
|
|
112
|
+
display: none;
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
}
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// COMPONENT STYLES - HEADER
|
|
118
|
+
// ============================================================================
|
|
119
|
+
generateHeaderStyles() {
|
|
120
|
+
return `
|
|
49
121
|
.header {
|
|
50
|
-
padding:
|
|
51
|
-
border-bottom:
|
|
122
|
+
padding: ${this.SPACING.lg}px;
|
|
123
|
+
border-bottom: ${this.BORDER_STYLES.primary};
|
|
52
124
|
display: flex;
|
|
53
125
|
justify-content: space-between;
|
|
54
126
|
align-items: center;
|
|
@@ -56,7 +128,7 @@ class StyleManager {
|
|
|
56
128
|
|
|
57
129
|
.header h2 {
|
|
58
130
|
margin: 0;
|
|
59
|
-
font-size:
|
|
131
|
+
font-size: ${this.FONT_SIZES.h2};
|
|
60
132
|
font-weight: 600;
|
|
61
133
|
}
|
|
62
134
|
|
|
@@ -67,8 +139,8 @@ class StyleManager {
|
|
|
67
139
|
cursor: pointer;
|
|
68
140
|
color: #666;
|
|
69
141
|
padding: 0;
|
|
70
|
-
width:
|
|
71
|
-
height:
|
|
142
|
+
width: ${this.MODAL_SIZES.headerHeight};
|
|
143
|
+
height: ${this.MODAL_SIZES.headerHeight};
|
|
72
144
|
display: flex;
|
|
73
145
|
align-items: center;
|
|
74
146
|
justify-content: center;
|
|
@@ -78,29 +150,38 @@ class StyleManager {
|
|
|
78
150
|
.close:hover {
|
|
79
151
|
background: #f0f0f0;
|
|
80
152
|
}
|
|
81
|
-
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
// ============================================================================
|
|
156
|
+
// COMPONENT STYLES - BODY & FORM
|
|
157
|
+
// ============================================================================
|
|
158
|
+
generateBodyStyles() {
|
|
159
|
+
return `
|
|
82
160
|
.body {
|
|
83
|
-
padding:
|
|
161
|
+
padding: ${this.SPACING.lg}px;
|
|
84
162
|
}
|
|
85
|
-
|
|
163
|
+
`;
|
|
164
|
+
}
|
|
165
|
+
generateFormStyles() {
|
|
166
|
+
return `
|
|
86
167
|
.form-group {
|
|
87
|
-
margin-bottom:
|
|
168
|
+
margin-bottom: ${this.SPACING.lg}px;
|
|
88
169
|
}
|
|
89
170
|
|
|
90
171
|
.label {
|
|
91
172
|
display: block;
|
|
92
|
-
margin-bottom:
|
|
173
|
+
margin-bottom: ${this.SPACING.xs}px;
|
|
93
174
|
font-weight: 500;
|
|
94
|
-
font-size:
|
|
175
|
+
font-size: ${this.FONT_SIZES.label};
|
|
95
176
|
}
|
|
96
177
|
|
|
97
178
|
.input,
|
|
98
179
|
.textarea {
|
|
99
180
|
width: 100%;
|
|
100
|
-
padding:
|
|
101
|
-
border:
|
|
181
|
+
padding: ${this.SPACING.xs}px;
|
|
182
|
+
border: ${this.BORDER_STYLES.light};
|
|
102
183
|
border-radius: ${this.config.borderRadius};
|
|
103
|
-
font-size:
|
|
184
|
+
font-size: ${this.FONT_SIZES.body};
|
|
104
185
|
font-family: ${this.config.fontFamily};
|
|
105
186
|
box-sizing: border-box;
|
|
106
187
|
}
|
|
@@ -116,40 +197,92 @@ class StyleManager {
|
|
|
116
197
|
resize: vertical;
|
|
117
198
|
}
|
|
118
199
|
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
|
|
200
|
+
.checkbox-group {
|
|
201
|
+
display: flex;
|
|
202
|
+
align-items: center;
|
|
203
|
+
gap: ${this.SPACING.xs}px;
|
|
204
|
+
margin-top: ${this.SPACING.md}px;
|
|
122
205
|
}
|
|
123
206
|
|
|
124
|
-
.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
207
|
+
.checkbox {
|
|
208
|
+
width: 18px;
|
|
209
|
+
height: 18px;
|
|
210
|
+
cursor: pointer;
|
|
128
211
|
}
|
|
129
212
|
|
|
130
|
-
.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
213
|
+
.checkbox-label {
|
|
214
|
+
margin: 0;
|
|
215
|
+
font-size: ${this.FONT_SIZES.body};
|
|
216
|
+
cursor: pointer;
|
|
217
|
+
user-select: none;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.error {
|
|
221
|
+
color: ${this.config.dangerColor};
|
|
222
|
+
font-size: ${this.FONT_SIZES.small};
|
|
223
|
+
margin-top: 4px;
|
|
224
|
+
}
|
|
225
|
+
`;
|
|
226
|
+
}
|
|
227
|
+
// ============================================================================
|
|
228
|
+
// COMPONENT STYLES - BUTTONS & CONTROLS
|
|
229
|
+
// ============================================================================
|
|
230
|
+
generateButtonStyles() {
|
|
231
|
+
return `
|
|
232
|
+
.footer {
|
|
233
|
+
padding: ${this.SPACING.lg}px;
|
|
234
|
+
border-top: ${this.BORDER_STYLES.primary};
|
|
235
|
+
display: flex;
|
|
236
|
+
justify-content: flex-end;
|
|
237
|
+
gap: ${this.SPACING.xs}px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.btn {
|
|
241
|
+
padding: ${this.SPACING.xs}px ${this.SPACING.md}px;
|
|
242
|
+
border: none;
|
|
136
243
|
border-radius: ${this.config.borderRadius};
|
|
244
|
+
cursor: pointer;
|
|
245
|
+
font-size: ${this.FONT_SIZES.body};
|
|
246
|
+
font-weight: 500;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.btn-primary {
|
|
250
|
+
background: ${this.config.primaryColor};
|
|
251
|
+
color: white;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.btn-primary:hover {
|
|
255
|
+
opacity: 0.9;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.btn-primary:disabled {
|
|
259
|
+
opacity: 0.5;
|
|
260
|
+
cursor: not-allowed;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.btn-secondary {
|
|
264
|
+
background: #6c757d;
|
|
265
|
+
color: white;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.btn-secondary:hover {
|
|
269
|
+
opacity: 0.9;
|
|
137
270
|
}
|
|
138
271
|
|
|
139
272
|
.redaction-controls {
|
|
140
|
-
margin-top:
|
|
273
|
+
margin-top: ${this.SPACING.xs}px;
|
|
141
274
|
display: flex;
|
|
142
|
-
gap:
|
|
275
|
+
gap: ${this.SPACING.xs}px;
|
|
143
276
|
}
|
|
144
277
|
|
|
145
278
|
.btn-redact,
|
|
146
279
|
.btn-clear {
|
|
147
|
-
padding:
|
|
148
|
-
border:
|
|
280
|
+
padding: ${this.SPACING.xs}px ${this.SPACING.md}px;
|
|
281
|
+
border: ${this.BORDER_STYLES.light};
|
|
149
282
|
border-radius: ${this.config.borderRadius};
|
|
150
283
|
background: white;
|
|
151
284
|
cursor: pointer;
|
|
152
|
-
font-size:
|
|
285
|
+
font-size: ${this.FONT_SIZES.body};
|
|
153
286
|
}
|
|
154
287
|
|
|
155
288
|
.btn-redact:hover,
|
|
@@ -163,17 +296,43 @@ class StyleManager {
|
|
|
163
296
|
border-color: ${this.config.primaryColor};
|
|
164
297
|
}
|
|
165
298
|
|
|
299
|
+
.screenshot-container {
|
|
300
|
+
margin-top: ${this.SPACING.xs}px;
|
|
301
|
+
position: relative;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.screenshot {
|
|
305
|
+
max-width: 100%;
|
|
306
|
+
border: ${this.BORDER_STYLES.light};
|
|
307
|
+
border-radius: ${this.config.borderRadius};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.redaction-canvas {
|
|
311
|
+
position: absolute;
|
|
312
|
+
top: 0;
|
|
313
|
+
left: 0;
|
|
314
|
+
cursor: crosshair;
|
|
315
|
+
border: 2px solid ${this.config.primaryColor};
|
|
316
|
+
border-radius: ${this.config.borderRadius};
|
|
317
|
+
}
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
320
|
+
// ============================================================================
|
|
321
|
+
// COMPONENT STYLES - PII DETECTION
|
|
322
|
+
// ============================================================================
|
|
323
|
+
generatePIIStyles() {
|
|
324
|
+
return `
|
|
166
325
|
.pii-section {
|
|
167
|
-
margin-top:
|
|
168
|
-
padding:
|
|
326
|
+
margin-top: ${this.SPACING.lg}px;
|
|
327
|
+
padding: ${this.SPACING.md}px;
|
|
169
328
|
background: #fff3cd;
|
|
170
329
|
border: 1px solid #ffc107;
|
|
171
330
|
border-radius: ${this.config.borderRadius};
|
|
172
331
|
}
|
|
173
332
|
|
|
174
333
|
.pii-title {
|
|
175
|
-
margin: 0 0
|
|
176
|
-
font-size:
|
|
334
|
+
margin: 0 0 ${this.SPACING.xs}px 0;
|
|
335
|
+
font-size: ${this.FONT_SIZES.body};
|
|
177
336
|
font-weight: 600;
|
|
178
337
|
color: #856404;
|
|
179
338
|
}
|
|
@@ -181,7 +340,7 @@ class StyleManager {
|
|
|
181
340
|
.pii-list {
|
|
182
341
|
margin: 0;
|
|
183
342
|
padding-left: 20px;
|
|
184
|
-
font-size:
|
|
343
|
+
font-size: ${this.FONT_SIZES.sr};
|
|
185
344
|
color: #856404;
|
|
186
345
|
}
|
|
187
346
|
|
|
@@ -192,61 +351,16 @@ class StyleManager {
|
|
|
192
351
|
background: #ffc107;
|
|
193
352
|
color: #856404;
|
|
194
353
|
border-radius: 12px;
|
|
195
|
-
font-size:
|
|
354
|
+
font-size: ${this.FONT_SIZES.small};
|
|
196
355
|
font-weight: 500;
|
|
197
356
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
.checkbox {
|
|
207
|
-
width: 18px;
|
|
208
|
-
height: 18px;
|
|
209
|
-
cursor: pointer;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.checkbox-label {
|
|
213
|
-
margin: 0;
|
|
214
|
-
font-size: 14px;
|
|
215
|
-
cursor: pointer;
|
|
216
|
-
user-select: none;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.footer {
|
|
220
|
-
padding: 20px;
|
|
221
|
-
border-top: 1px solid #e0e0e0;
|
|
222
|
-
display: flex;
|
|
223
|
-
justify-content: flex-end;
|
|
224
|
-
gap: 10px;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
.btn {
|
|
228
|
-
padding: 10px 20px;
|
|
229
|
-
border: none;
|
|
230
|
-
border-radius: ${this.config.borderRadius};
|
|
231
|
-
cursor: pointer;
|
|
232
|
-
font-size: 14px;
|
|
233
|
-
font-weight: 500;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
.btn-primary {
|
|
237
|
-
background: ${this.config.primaryColor};
|
|
238
|
-
color: white;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.btn-primary:hover {
|
|
242
|
-
opacity: 0.9;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.btn-primary:disabled {
|
|
246
|
-
opacity: 0.5;
|
|
247
|
-
cursor: not-allowed;
|
|
248
|
-
}
|
|
249
|
-
|
|
357
|
+
`;
|
|
358
|
+
}
|
|
359
|
+
// ============================================================================
|
|
360
|
+
// COMPONENT STYLES - LOADING STATE
|
|
361
|
+
// ============================================================================
|
|
362
|
+
generateLoadingStyles() {
|
|
363
|
+
return `
|
|
250
364
|
.btn.loading {
|
|
251
365
|
position: relative;
|
|
252
366
|
padding-left: 2.5rem;
|
|
@@ -269,7 +383,13 @@ class StyleManager {
|
|
|
269
383
|
@keyframes spinner {
|
|
270
384
|
to { transform: rotate(360deg); }
|
|
271
385
|
}
|
|
272
|
-
|
|
386
|
+
`;
|
|
387
|
+
}
|
|
388
|
+
// ============================================================================
|
|
389
|
+
// COMPONENT STYLES - ACCESSIBILITY
|
|
390
|
+
// ============================================================================
|
|
391
|
+
generateAccessibilityStyles() {
|
|
392
|
+
return `
|
|
273
393
|
.sr-only {
|
|
274
394
|
position: absolute;
|
|
275
395
|
width: 1px;
|
|
@@ -281,20 +401,110 @@ class StyleManager {
|
|
|
281
401
|
white-space: nowrap;
|
|
282
402
|
border-width: 0;
|
|
283
403
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
404
|
+
`;
|
|
405
|
+
}
|
|
406
|
+
// ============================================================================
|
|
407
|
+
// RESPONSIVE STYLES - TABLET (≤768px)
|
|
408
|
+
// ============================================================================
|
|
409
|
+
generateTabletResponsiveStyles() {
|
|
410
|
+
return `
|
|
411
|
+
@media (max-width: ${this.BREAKPOINTS.tablet}px) {
|
|
412
|
+
.modal {
|
|
413
|
+
width: 95%;
|
|
414
|
+
max-width: ${this.MODAL_SIZES.tablet};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.header {
|
|
418
|
+
padding: ${this.SPACING.md}px;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.body {
|
|
422
|
+
padding: ${this.SPACING.md}px;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.footer {
|
|
426
|
+
padding: ${this.SPACING.md}px;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/* Prevent iOS zoom on input focus (requires 16px minimum) */
|
|
430
|
+
.input,
|
|
431
|
+
.textarea {
|
|
432
|
+
padding: ${this.SPACING.xs}px;
|
|
433
|
+
font-size: 16px;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.textarea {
|
|
437
|
+
min-height: 80px;
|
|
438
|
+
}
|
|
292
439
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
440
|
+
`;
|
|
441
|
+
}
|
|
442
|
+
// ============================================================================
|
|
443
|
+
// RESPONSIVE STYLES - MOBILE (≤480px)
|
|
444
|
+
// ============================================================================
|
|
445
|
+
generateMobileResponsiveStyles() {
|
|
446
|
+
return `
|
|
447
|
+
@media (max-width: ${this.BREAKPOINTS.mobile}px) {
|
|
448
|
+
.modal {
|
|
449
|
+
width: ${this.MODAL_SIZES.mobilePercent};
|
|
450
|
+
max-width: 100%;
|
|
451
|
+
max-height: 95vh;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.header {
|
|
455
|
+
padding: ${this.SPACING.sm}px;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.header h2 {
|
|
459
|
+
font-size: ${this.FONT_SIZES.h2Mobile};
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.body {
|
|
463
|
+
padding: ${this.SPACING.sm}px;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.footer {
|
|
467
|
+
padding: ${this.SPACING.sm}px;
|
|
468
|
+
flex-direction: column;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.btn {
|
|
472
|
+
width: 100%;
|
|
473
|
+
padding: ${this.SPACING.md}px;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.input,
|
|
477
|
+
.textarea {
|
|
478
|
+
padding: ${this.SPACING.xs}px;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.textarea {
|
|
482
|
+
resize: none;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.redaction-controls {
|
|
486
|
+
flex-direction: column;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.btn-redact,
|
|
490
|
+
.btn-clear {
|
|
491
|
+
width: 100%;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.pii-section {
|
|
495
|
+
padding: ${this.SPACING.sm}px;
|
|
496
|
+
margin-top: ${this.SPACING.md}px;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.label {
|
|
500
|
+
font-size: ${this.FONT_SIZES.labelMobile};
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.close {
|
|
504
|
+
width: 28px;
|
|
505
|
+
height: 28px;
|
|
506
|
+
font-size: 20px;
|
|
507
|
+
}
|
|
298
508
|
}
|
|
299
509
|
`;
|
|
300
510
|
}
|
|
@@ -12,7 +12,8 @@ class TemplateManager {
|
|
|
12
12
|
this.config = {
|
|
13
13
|
title: config.title || 'Report a Bug',
|
|
14
14
|
titlePlaceholder: config.titlePlaceholder || 'Brief description of the issue',
|
|
15
|
-
descriptionPlaceholder: config.descriptionPlaceholder ||
|
|
15
|
+
descriptionPlaceholder: config.descriptionPlaceholder ||
|
|
16
|
+
'Detailed description of what happened...',
|
|
16
17
|
submitButtonText: config.submitButtonText || 'Submit Bug Report',
|
|
17
18
|
cancelButtonText: config.cancelButtonText || 'Cancel',
|
|
18
19
|
showScreenshot: config.showScreenshot !== false,
|