export function accessibilityFeedbackForm(form: FormTs) {
// Accessibility Feedback Form - Collect a11y feedback from users with disabilities
// Demonstrates: CheckboxList, RadioButton, MatrixQuestion, Slider, ThumbRating, conditional sections
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Accessibility Feedback',
computedValue: () => 'Help us make our website accessible to everyone. Your feedback directly improves our inclusive design.',
customStyles: {
background: 'linear-gradient(135deg, #0ea5e9 0%, #6366f1 100%)',
color: 'white',
padding: '28px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Assistive Technology
// ============================================
const techSection = form.addSubform('assistiveTech', {
title: 'Your Assistive Technology'
});
techSection.addRow(row => {
row.addCheckboxList('assistiveTools', {
label: 'Which assistive technologies do you use? (Select all that apply)',
options: [
{ id: 'screen-reader', name: 'Screen Reader (JAWS, NVDA, VoiceOver)' },
{ id: 'magnifier', name: 'Screen Magnifier' },
{ id: 'voice-control', name: 'Voice Control (Dragon, Voice Control)' },
{ id: 'switch', name: 'Switch Device' },
{ id: 'keyboard-only', name: 'Keyboard Only (no mouse)' },
{ id: 'high-contrast', name: 'High Contrast Mode' },
{ id: 'text-to-speech', name: 'Text-to-Speech' },
{ id: 'other', name: 'Other Assistive Technology' }
],
orientation: 'vertical'
});
});
techSection.addRow(row => {
row.addTextbox('screenReaderName', {
label: 'Which screen reader do you primarily use?',
placeholder: 'e.g., JAWS, NVDA, VoiceOver, TalkBack...',
isVisible: () => {
const tools = techSection.checkboxList('assistiveTools')?.value() || [];
return tools.includes('screen-reader');
}
});
});
techSection.addRow(row => {
row.addTextbox('otherTech', {
label: 'Please describe your other assistive technology',
placeholder: 'Type of technology you use...',
isVisible: () => {
const tools = techSection.checkboxList('assistiveTools')?.value() || [];
return tools.includes('other');
}
});
});
// ============================================
// SECTION 2: Accessibility Rating
// ============================================
const ratingSection = form.addSubform('accessibilityRating', {
title: 'Accessibility Rating',
isVisible: () => (techSection.checkboxList('assistiveTools')?.value()?.length ?? 0) > 0,
customStyles: { backgroundColor: '#f0f9ff', padding: '16px', borderRadius: '8px' }
});
ratingSection.addRow(row => {
row.addMatrixQuestion('a11yAspects', {
label: 'Please rate the following accessibility aspects:',
rows: [
{ id: 'navigation', label: 'Keyboard Navigation', isRequired: true },
{ id: 'screen-reader', label: 'Screen Reader Compatibility', isRequired: true },
{ id: 'contrast', label: 'Color Contrast', isRequired: true },
{ id: 'text-size', label: 'Text Size & Readability', isRequired: true },
{ id: 'forms', label: 'Form Labels & Instructions', isRequired: false },
{ id: 'errors', label: 'Error Messages', isRequired: false },
{ id: 'media', label: 'Media (Images, Videos)', isRequired: false }
],
columns: [
{ id: 'unusable', label: 'Unusable' },
{ id: 'difficult', label: 'Difficult' },
{ id: 'ok', label: 'OK' },
{ id: 'good', label: 'Good' },
{ id: 'excellent', label: 'Excellent' },
{ id: 'na', label: 'N/A' }
],
striped: true,
fullWidth: true
});
});
ratingSection.addSpacer();
ratingSection.addRow(row => {
row.addSlider('overallAccessibility', {
label: 'Overall accessibility score (0 = completely inaccessible, 100 = fully accessible)',
min: 0,
max: 100,
step: 5,
defaultValue: 50,
showValue: true,
unit: '%'
});
});
// ============================================
// SECTION 3: Specific Barriers
// ============================================
const barriersSection = form.addSubform('barriers', {
title: 'Accessibility Barriers',
isVisible: () => {
const score = ratingSection.slider('overallAccessibility')?.value();
return score !== null && score !== undefined;
}
});
barriersSection.addRow(row => {
row.addCheckboxList('barrierTypes', {
label: 'What types of barriers did you encounter?',
options: [
{ id: 'focus', name: 'Focus not visible or hard to see' },
{ id: 'keyboard-trap', name: 'Keyboard trap (couldn\'t navigate away)' },
{ id: 'missing-labels', name: 'Missing or confusing labels' },
{ id: 'timing', name: 'Content disappeared too quickly' },
{ id: 'motion', name: 'Distracting animations or motion' },
{ id: 'contrast', name: 'Low color contrast' },
{ id: 'small-targets', name: 'Click/touch targets too small' },
{ id: 'complex-layout', name: 'Complex or confusing layout' },
{ id: 'pdf', name: 'Inaccessible PDFs or documents' },
{ id: 'captcha', name: 'CAPTCHA not accessible' }
],
orientation: 'vertical'
});
});
barriersSection.addSpacer();
barriersSection.addRow(row => {
row.addTextarea('barrierDescription', {
label: 'Please describe the accessibility issue you encountered',
placeholder: 'What were you trying to do? What happened? Which page or feature was affected?',
rows: 4,
autoExpand: true
});
});
barriersSection.addRow(row => {
row.addTextbox('pageUrl', {
label: 'Page URL where you encountered the issue (if known)',
placeholder: 'https://...'
});
});
// ============================================
// SECTION 4: Impact Assessment
// ============================================
const impactSection = form.addSubform('impact', {
title: 'Impact Assessment',
isVisible: () => {
const barriers = barriersSection.checkboxList('barrierTypes')?.value() || [];
return barriers.length > 0 || (barriersSection.textarea('barrierDescription')?.value()?.length ?? 0) > 0;
}
});
impactSection.addRow(row => {
row.addRadioButton('taskCompletion', {
label: 'Were you able to complete your task?',
options: [
{ id: 'yes', name: 'Yes, successfully' },
{ id: 'partial', name: 'Partially, with difficulty' },
{ id: 'workaround', name: 'Yes, but needed a workaround' },
{ id: 'no', name: 'No, I could not complete my task' }
],
orientation: 'vertical'
});
});
impactSection.addRow(row => {
row.addRadioButton('severity', {
label: 'How severe was this accessibility issue?',
options: [
{ id: 'critical', name: 'Critical - Completely blocked my use' },
{ id: 'major', name: 'Major - Significant difficulty' },
{ id: 'minor', name: 'Minor - Inconvenience but usable' },
{ id: 'cosmetic', name: 'Cosmetic - Small annoyance' }
],
orientation: 'vertical',
isVisible: () => {
const completion = impactSection.radioButton('taskCompletion')?.value();
return completion !== 'yes';
}
});
});
impactSection.addRow(row => {
row.addEmojiRating('frustration', {
label: 'How frustrated did this issue make you feel?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
// ============================================
// SECTION 5: Suggestions
// ============================================
const suggestionsSection = form.addSubform('suggestions', {
title: 'Your Suggestions',
isVisible: () => impactSection.emojiRating('frustration')?.value() !== null
});
suggestionsSection.addRow(row => {
row.addTextarea('improvementSuggestion', {
label: 'How could we improve the accessibility of our website?',
placeholder: 'Your suggestions help us prioritize fixes...',
rows: 3,
autoExpand: true
});
});
suggestionsSection.addSpacer();
suggestionsSection.addRow(row => {
row.addThumbRating('wouldReturn', {
label: 'Would you use our website again despite the accessibility issues?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
alignment: 'center'
});
});
// ============================================
// SECTION 6: Contact Information
// ============================================
const contactSection = form.addSubform('contact', {
title: 'Follow-up (Optional)',
isVisible: () => suggestionsSection.thumbRating('wouldReturn')?.value() !== null
});
contactSection.addRow(row => {
row.addCheckbox('contactConsent', {
label: 'You may contact me for more details about my accessibility experience'
});
});
contactSection.addRow(row => {
row.addEmail('contactEmail', {
label: 'Your email address',
placeholder: 'email@example.com',
isVisible: () => contactSection.checkbox('contactConsent')?.value() === true,
isRequired: () => contactSection.checkbox('contactConsent')?.value() === true
});
});
contactSection.addRow(row => {
row.addCheckbox('betaTester', {
label: 'I\'d like to participate in accessibility testing of new features',
isVisible: () => contactSection.checkbox('contactConsent')?.value() === true
});
});
// ============================================
// SECTION 7: Summary
// ============================================
const summarySection = form.addSubform('summary', {
title: 'Feedback Summary',
isVisible: () => suggestionsSection.thumbRating('wouldReturn')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryContent', {
computedValue: () => {
const tools = techSection.checkboxList('assistiveTools')?.value() || [];
const score = ratingSection.slider('overallAccessibility')?.value();
const barriers = barriersSection.checkboxList('barrierTypes')?.value() || [];
const completion = impactSection.radioButton('taskCompletion')?.value();
const severity = impactSection.radioButton('severity')?.value();
const wouldReturn = suggestionsSection.thumbRating('wouldReturn')?.value();
if (tools.length === 0) return '';
let summary = 'Accessibility Report\n';
summary += `${'═'.repeat(25)}\n\n`;
summary += `Assistive Tech: ${tools.length} tools\n`;
if (score !== null && score !== undefined) {
summary += `Overall Score: ${score}%\n`;
}
if (barriers.length > 0) {
summary += `Barriers Found: ${barriers.length}\n`;
}
if (completion) {
const completionLabels: Record<string, string> = {
'yes': 'Task completed',
'partial': 'Partial completion',
'workaround': 'Workaround needed',
'no': 'Task blocked'
};
summary += `Task Status: ${completionLabels[completion]}\n`;
}
if (severity) {
summary += `Severity: ${severity.charAt(0).toUpperCase()}${severity.slice(1)}\n`;
}
if (wouldReturn) {
summary += `\nWould Return: ${wouldReturn === 'up' ? 'Yes' : 'No'}\n`;
}
return summary;
},
customStyles: () => {
const score = ratingSection.slider('overallAccessibility')?.value() ?? 50;
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (score >= 70) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
} else if (score >= 40) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Accessibility Feedback',
isVisible: () => suggestionsSection.thumbRating('wouldReturn')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your accessibility feedback is invaluable. We review every report and prioritize fixes based on impact. Together, we can make the web more inclusive for everyone.'
});
}