export function bugReportForm(form: FormTs) {
// Bug Report Form - Technical issue reporting for software/apps
// Demonstrates: Dropdown, RadioButton, Textbox, Textarea, CheckboxList, RatingScale, MatrixQuestion, Pages, dynamic styling
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Report a Bug',
computedValue: () => 'Help us squash bugs and improve your experience',
customStyles: {
backgroundColor: '#dc2626',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// MULTI-PAGE STRUCTURE
// ============================================
const pages = form.addPages('bugPages', {
heightMode: 'current-page'
});
// ============================================
// PAGE 1: Bug Overview
// ============================================
const page1 = pages.addPage('overview');
page1.addRow(row => {
row.addTextPanel('page1Title', {
label: 'Step 1 of 3: Bug Overview',
customStyles: {
backgroundColor: '#fef2f2',
padding: '12px 16px',
borderRadius: '8px',
fontWeight: 'bold',
color: '#991b1b'
}
});
});
const basicInfo = page1.addSubform('basicInfo', {
title: 'Basic Information',
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' }
});
basicInfo.addRow(row => {
row.addTextbox('bugTitle', {
label: 'Bug Title',
placeholder: 'Brief, descriptive title (e.g., "Login button not responding")',
isRequired: true,
maxLength: 100
});
});
basicInfo.addRow(row => {
row.addDropdown('featureArea', {
label: 'Feature/Area Affected',
options: [
{ id: 'authentication', name: 'Login/Authentication' },
{ id: 'navigation', name: 'Navigation/Menu' },
{ id: 'forms', name: 'Forms/Input' },
{ id: 'payments', name: 'Payments/Checkout' },
{ id: 'search', name: 'Search' },
{ id: 'profile', name: 'User Profile/Settings' },
{ id: 'notifications', name: 'Notifications' },
{ id: 'dashboard', name: 'Dashboard' },
{ id: 'reports', name: 'Reports/Analytics' },
{ id: 'integrations', name: 'Integrations' },
{ id: 'performance', name: 'Performance' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select affected area',
isRequired: true
}, '1fr');
row.addDropdown('bugType', {
label: 'Bug Type',
options: [
{ id: 'crash', name: 'Crash/App freeze' },
{ id: 'ui', name: 'UI/Visual issue' },
{ id: 'functional', name: 'Feature not working' },
{ id: 'data', name: 'Data issue/corruption' },
{ id: 'performance', name: 'Slow/Performance' },
{ id: 'security', name: 'Security concern' },
{ id: 'accessibility', name: 'Accessibility' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select bug type'
}, '1fr');
});
const severitySection = page1.addSubform('severitySection', {
title: 'Severity & Impact',
customStyles: () => {
const severity = severitySection.radioButton('severity')?.value();
if (severity === 'critical') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #dc2626' };
if (severity === 'high') return { backgroundColor: '#ffedd5', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #ea580c' };
if (severity === 'medium') return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #ca8a04' };
if (severity === 'low') return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px', borderLeft: '4px solid #10b981' };
return { padding: '16px', borderRadius: '8px', border: '1px dashed #cbd5e1' };
}
});
severitySection.addRow(row => {
row.addRadioButton('severity', {
label: 'Bug Severity',
options: [
{ id: 'critical', name: 'Critical - App unusable, data loss' },
{ id: 'high', name: 'High - Major feature broken' },
{ id: 'medium', name: 'Medium - Feature impaired but workaround exists' },
{ id: 'low', name: 'Low - Minor inconvenience' }
],
orientation: 'vertical',
isRequired: true
});
});
severitySection.addRow(row => {
row.addRadioButton('frequency', {
label: 'How often does this happen?',
options: [
{ id: 'always', name: 'Every time (100%)' },
{ id: 'often', name: 'Often (>50%)' },
{ id: 'sometimes', name: 'Sometimes (<50%)' },
{ id: 'rare', name: 'Rarely' },
{ id: 'once', name: 'Happened once' }
],
orientation: 'horizontal'
});
});
severitySection.addRow(row => {
row.addCheckboxList('impact', {
label: 'What\'s impacted?',
options: [
{ id: 'blocking', name: 'Blocks my work completely' },
{ id: 'data-risk', name: 'Risk of data loss' },
{ id: 'security', name: 'Security implications' },
{ id: 'many-users', name: 'Affects many users' },
{ id: 'customer-facing', name: 'Customer-facing issue' },
{ id: 'deadline', name: 'Blocking a deadline' }
],
orientation: 'vertical'
});
});
page1.addRow(row => {
row.addEmpty('1fr');
row.addButton('next1', {
label: 'Next: Details & Steps',
onClick: () => pages.goToPage('details')
});
});
// ============================================
// PAGE 2: Bug Details & Reproduction
// ============================================
const page2 = pages.addPage('details');
page2.addRow(row => {
row.addTextPanel('page2Title', {
label: 'Step 2 of 3: Details & Reproduction',
customStyles: {
backgroundColor: '#fef2f2',
padding: '12px 16px',
borderRadius: '8px',
fontWeight: 'bold',
color: '#991b1b'
}
});
});
const descSection = page2.addSubform('descSection', {
title: 'Bug Description',
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' }
});
descSection.addRow(row => {
row.addTextarea('whatHappened', {
label: 'What happened? (Actual behavior)',
placeholder: 'Describe exactly what you observed. Be specific about error messages, unexpected behavior, etc.',
isRequired: true,
rows: 3,
autoExpand: true
});
});
descSection.addRow(row => {
row.addTextarea('expectedBehavior', {
label: 'What did you expect to happen? (Expected behavior)',
placeholder: 'Describe what should have happened instead.',
isRequired: true,
rows: 2,
autoExpand: true
});
});
const stepsSection = page2.addSubform('stepsSection', {
title: 'Steps to Reproduce',
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' }
});
stepsSection.addRow(row => {
row.addTextPanel('stepsHelp', {
computedValue: () => 'List the exact steps to reproduce this bug. The more detail, the faster we can fix it.',
customStyles: {
backgroundColor: '#f1f5f9',
padding: '12px',
borderRadius: '4px',
fontSize: '14px',
color: '#475569'
}
});
});
stepsSection.addRow(row => {
row.addTextarea('step1', {
label: 'Step 1',
placeholder: 'e.g., Go to the login page',
isRequired: true,
rows: 1,
autoExpand: true
});
});
stepsSection.addRow(row => {
row.addTextarea('step2', {
label: 'Step 2',
placeholder: 'e.g., Enter valid credentials',
rows: 1,
autoExpand: true
});
});
stepsSection.addRow(row => {
row.addTextarea('step3', {
label: 'Step 3',
placeholder: 'e.g., Click the Login button',
rows: 1,
autoExpand: true
});
});
stepsSection.addRow(row => {
row.addTextarea('additionalSteps', {
label: 'Additional steps (if needed)',
placeholder: 'Continue with steps 4, 5, etc. if applicable',
rows: 2,
autoExpand: true
});
});
const evidenceSection = page2.addSubform('evidenceSection', {
title: 'Evidence (Optional)'
});
evidenceSection.addRow(row => {
row.addTextbox('screenshotUrl', {
label: 'Screenshot URL',
placeholder: 'Paste a link to screenshot (Imgur, Dropbox, etc.)'
}, '1fr');
row.addTextbox('videoUrl', {
label: 'Screen Recording URL',
placeholder: 'Paste a link to video (Loom, YouTube, etc.)'
}, '1fr');
});
evidenceSection.addRow(row => {
row.addTextarea('errorMessage', {
label: 'Error message (if any)',
placeholder: 'Copy and paste exact error text',
rows: 2,
autoExpand: true
});
});
page2.addRow(row => {
row.addButton('back2', {
label: 'Back',
onClick: () => pages.goToPage('overview')
});
row.addEmpty('1fr');
row.addButton('next2', {
label: 'Next: Environment',
onClick: () => pages.goToPage('environment')
});
});
// ============================================
// PAGE 3: Environment & Submit
// ============================================
const page3 = pages.addPage('environment');
page3.addRow(row => {
row.addTextPanel('page3Title', {
label: 'Step 3 of 3: Environment & Submit',
customStyles: {
backgroundColor: '#fef2f2',
padding: '12px 16px',
borderRadius: '8px',
fontWeight: 'bold',
color: '#991b1b'
}
});
});
const envSection = page3.addSubform('envSection', {
title: 'Environment Details',
customStyles: { padding: '16px', borderRadius: '8px', border: '1px solid #e2e8f0' }
});
envSection.addRow(row => {
row.addDropdown('platform', {
label: 'Platform',
options: [
{ id: 'web', name: 'Web Browser' },
{ id: 'ios', name: 'iOS App' },
{ id: 'android', name: 'Android App' },
{ id: 'desktop-win', name: 'Desktop - Windows' },
{ id: 'desktop-mac', name: 'Desktop - macOS' },
{ id: 'desktop-linux', name: 'Desktop - Linux' }
],
placeholder: 'Select platform'
}, '1fr');
row.addDropdown('browser', {
label: 'Browser (if web)',
options: [
{ id: 'chrome', name: 'Chrome' },
{ id: 'firefox', name: 'Firefox' },
{ id: 'safari', name: 'Safari' },
{ id: 'edge', name: 'Edge' },
{ id: 'opera', name: 'Opera' },
{ id: 'brave', name: 'Brave' },
{ id: 'other', name: 'Other' }
],
placeholder: 'Select browser',
isVisible: () => envSection.dropdown('platform')?.value() === 'web'
}, '1fr');
});
envSection.addRow(row => {
row.addDropdown('deviceType', {
label: 'Device Type',
options: [
{ id: 'desktop', name: 'Desktop/Laptop' },
{ id: 'phone', name: 'Phone' },
{ id: 'tablet', name: 'Tablet' }
],
placeholder: 'Select device'
}, '1fr');
row.addTextbox('osVersion', {
label: 'OS Version',
placeholder: 'e.g., Windows 11, iOS 17.2, Android 14'
}, '1fr');
});
envSection.addRow(row => {
row.addTextbox('appVersion', {
label: 'App/Website Version (if known)',
placeholder: 'e.g., v2.5.1'
}, '1fr');
row.addDropdown('accountType', {
label: 'Account Type',
options: [
{ id: 'free', name: 'Free User' },
{ id: 'trial', name: 'Trial User' },
{ id: 'paid', name: 'Paid/Premium' },
{ id: 'enterprise', name: 'Enterprise' },
{ id: 'admin', name: 'Admin/Staff' }
],
placeholder: 'Select account type'
}, '1fr');
});
const workaroundSection = page3.addSubform('workaroundSection', {
title: 'Workaround & Contact'
});
workaroundSection.addRow(row => {
row.addRadioButton('hasWorkaround', {
label: 'Did you find a workaround?',
options: [
{ id: 'yes', name: 'Yes' },
{ id: 'no', name: 'No' }
],
orientation: 'horizontal'
});
});
workaroundSection.addRow(row => {
row.addTextarea('workaroundDesc', {
label: 'Describe the workaround',
placeholder: 'How did you work around this issue?',
rows: 2,
autoExpand: true,
isVisible: () => workaroundSection.radioButton('hasWorkaround')?.value() === 'yes'
});
});
workaroundSection.addRow(row => {
row.addEmail('contactEmail', {
label: 'Your email (optional, for follow-up)',
placeholder: 'your@email.com'
});
});
// Summary Section
const summarySection = page3.addSubform('summarySection', {
title: 'Bug Report Summary',
isVisible: () => basicInfo.textbox('bugTitle')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const title = basicInfo.textbox('bugTitle')?.value();
const area = basicInfo.dropdown('featureArea')?.value();
const severity = severitySection.radioButton('severity')?.value();
const frequency = severitySection.radioButton('frequency')?.value();
const platform = envSection.dropdown('platform')?.value();
const impacts = severitySection.checkboxList('impact')?.value() || [];
if (!title) return '';
const severityLabels: Record<string, string> = {
'critical': 'CRITICAL',
'high': 'High',
'medium': 'Medium',
'low': 'Low'
};
const severityEmojis: Record<string, string> = {
'critical': '🔴',
'high': '🟠',
'medium': '🟡',
'low': '🟢'
};
const frequencyLabels: Record<string, string> = {
'always': 'Every time',
'often': 'Often',
'sometimes': 'Sometimes',
'rare': 'Rarely',
'once': 'Once'
};
let summary = `BUG REPORT\n`;
summary += `${'═'.repeat(30)}\n\n`;
summary += `Title: ${title}\n`;
if (area) {
summary += `Area: ${area}\n`;
}
if (severity) {
summary += `\n${severityEmojis[severity] || '⚪'} Severity: ${severityLabels[severity] || severity}\n`;
}
if (frequency) {
summary += `Frequency: ${frequencyLabels[frequency] || frequency}\n`;
}
if (impacts.length > 0) {
summary += `\n⚠️ Impacts: ${impacts.length} factor(s)\n`;
}
if (platform) {
summary += `\nPlatform: ${platform}\n`;
}
summary += `\n📝 Ready to submit`;
return summary;
},
customStyles: () => {
const severity = severitySection.radioButton('severity')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (severity === 'critical') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #dc2626' };
} else if (severity === 'high') {
return { ...baseStyles, backgroundColor: '#ffedd5', borderLeft: '4px solid #ea580c' };
} else if (severity === 'medium') {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #ca8a04' };
} else if (severity === 'low') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
}
return { ...baseStyles, backgroundColor: '#f8fafc', borderLeft: '4px solid #dc2626' };
}
});
});
page3.addRow(row => {
row.addButton('back3', {
label: 'Back',
onClick: () => pages.goToPage('details')
});
row.addEmpty('1fr');
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: () => {
const severity = severitySection.radioButton('severity')?.value();
if (severity === 'critical') return 'Submit Critical Bug';
return 'Submit Bug Report';
},
isVisible: () => pages.currentPageIndex() === 2
});
form.configureCompletionScreen({
type: 'text',
title: 'Bug Report Submitted!',
message: 'Thank you for reporting this issue. Our team will investigate and work on a fix. You can track the status of your report in our issue tracker.'
});
}