export function releaseNotesFeedback(form: FormTs) {
// Release Notes Reaction Survey - Gauge user interest in new features
// Demonstrates: EmojiRating, CheckboxList, MatrixQuestion, StarRating, dynamic visibility, conditional styling
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'What do you think of our latest update?',
computedValue: () => 'Version 2.5 brings exciting new features and improvements. We\'d love to hear your thoughts!',
customStyles: {
backgroundColor: '#3b82f6',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Initial Reaction
// ============================================
const reactionSection = form.addSubform('reactionSection', {
title: 'Your First Reaction',
customStyles: () => {
const reaction = reactionSection.emojiRating('initialReaction')?.value();
if (reaction === 'excellent') return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (reaction === 'good') return { backgroundColor: '#dbeafe', padding: '16px', borderRadius: '8px' };
if (reaction === 'neutral') return { backgroundColor: '#f1f5f9', padding: '16px', borderRadius: '8px' };
if (reaction === 'bad' || reaction === 'very-bad') return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
return { padding: '16px', borderRadius: '8px', border: '1px dashed #cbd5e1' };
}
});
reactionSection.addRow(row => {
row.addEmojiRating('initialReaction', {
label: 'How do you feel about this update?',
preset: 'mood',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
reactionSection.addRow(row => {
row.addRadioButton('sawReleaseNotes', {
label: 'Did you read the release notes?',
options: [
{ id: 'read-all', name: 'Yes, I read everything' },
{ id: 'skimmed', name: 'I skimmed through them' },
{ id: 'headlines', name: 'Just the headlines' },
{ id: 'no', name: 'No, I haven\'t seen them yet' }
],
orientation: 'horizontal'
});
});
// ============================================
// SECTION 2: Feature Interest
// ============================================
const featuresSection = form.addSubform('featuresSection', {
title: 'New Features',
isVisible: () => reactionSection.emojiRating('initialReaction')?.value() !== null
});
featuresSection.addRow(row => {
row.addTextPanel('featuresIntro', {
computedValue: () => 'Here\'s what\'s new in this release. Select the features you\'re most interested in.',
customStyles: {
fontSize: '14px',
color: '#475569',
marginBottom: '12px'
}
});
});
featuresSection.addRow(row => {
row.addCheckboxList('interestedFeatures', {
label: 'Which new features are you excited about?',
options: [
{ id: 'dark-mode', name: 'Dark Mode - Easy on the eyes' },
{ id: 'keyboard-shortcuts', name: 'Keyboard Shortcuts - Work faster' },
{ id: 'export-csv', name: 'CSV Export - Get your data out easily' },
{ id: 'collaboration', name: 'Real-time Collaboration - Work together' },
{ id: 'templates', name: 'New Templates - Start quickly' },
{ id: 'mobile-app', name: 'Mobile App Improvements - Better on the go' },
{ id: 'integrations', name: 'New Integrations - Connect your tools' },
{ id: 'performance', name: 'Performance Improvements - Faster loading' }
],
orientation: 'vertical'
});
});
// Feature importance matrix
const importanceSection = featuresSection.addSubform('importanceSection', {
title: 'Feature Importance',
isVisible: () => {
const features = featuresSection.checkboxList('interestedFeatures')?.value() || [];
return features.length > 0;
},
customStyles: { marginTop: '16px', backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' }
});
importanceSection.addRow(row => {
row.addMatrixQuestion('featureImportance', {
label: 'How important are these features to your workflow?',
rows: () => {
const selected = featuresSection.checkboxList('interestedFeatures')?.value() || [];
const featureLabels: Record<string, string> = {
'dark-mode': 'Dark Mode',
'keyboard-shortcuts': 'Keyboard Shortcuts',
'export-csv': 'CSV Export',
'collaboration': 'Real-time Collaboration',
'templates': 'New Templates',
'mobile-app': 'Mobile App',
'integrations': 'New Integrations',
'performance': 'Performance'
};
return selected.map(id => ({
id,
label: featureLabels[id] || id,
isRequired: false
}));
},
columns: [
{ id: 'critical', label: 'Critical' },
{ id: 'important', label: 'Important' },
{ id: 'nice', label: 'Nice to Have' },
{ id: 'meh', label: 'Not for Me' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 3: Most Anticipated Feature
// ============================================
const anticipatedSection = form.addSubform('anticipatedSection', {
title: 'Your Top Pick',
isVisible: () => {
const features = featuresSection.checkboxList('interestedFeatures')?.value() || [];
return features.length > 1;
}
});
anticipatedSection.addRow(row => {
row.addRadioButton('topFeature', {
label: 'Which feature are you most excited to try first?',
options: () => {
const selected = featuresSection.checkboxList('interestedFeatures')?.value() || [];
const featureLabels: Record<string, string> = {
'dark-mode': 'Dark Mode',
'keyboard-shortcuts': 'Keyboard Shortcuts',
'export-csv': 'CSV Export',
'collaboration': 'Real-time Collaboration',
'templates': 'New Templates',
'mobile-app': 'Mobile App Improvements',
'integrations': 'New Integrations',
'performance': 'Performance Improvements'
};
return selected.map(id => ({
id,
name: featureLabels[id] || id
}));
},
orientation: 'vertical'
});
});
anticipatedSection.addRow(row => {
row.addTextarea('whyExcited', {
label: () => {
const top = anticipatedSection.radioButton('topFeature')?.value();
if (top) {
const labels: Record<string, string> = {
'dark-mode': 'Dark Mode',
'keyboard-shortcuts': 'Keyboard Shortcuts',
'export-csv': 'CSV Export',
'collaboration': 'Real-time Collaboration',
'templates': 'New Templates',
'mobile-app': 'Mobile App',
'integrations': 'New Integrations',
'performance': 'Performance'
};
return `Why are you most excited about ${labels[top] || top}?`;
}
return 'What makes this feature exciting for you?';
},
placeholder: 'Tell us how you plan to use it...',
rows: 2,
autoExpand: true,
isVisible: () => anticipatedSection.radioButton('topFeature')?.value() !== null
});
});
// ============================================
// SECTION 4: Bug Fixes & Improvements
// ============================================
const improvementsSection = form.addSubform('improvementsSection', {
title: 'Bug Fixes & Improvements',
isVisible: () => reactionSection.emojiRating('initialReaction')?.value() !== null
});
improvementsSection.addRow(row => {
row.addThumbRating('bugFixesRelevant', {
label: 'Were any of the bug fixes relevant to issues you experienced?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
alignment: 'center',
size: 'lg'
}, '1fr');
row.addThumbRating('improvementsNoticeable', {
label: 'Have you noticed performance improvements?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'Not yet',
alignment: 'center',
size: 'lg'
}, '1fr');
});
// Conditional follow-up for bug fixes
improvementsSection.addRow(row => {
row.addTextarea('bugFixFeedback', {
label: 'Which bug fix was most important to you?',
placeholder: 'Describe the issue that was fixed...',
rows: 2,
isVisible: () => improvementsSection.thumbRating('bugFixesRelevant')?.value() === 'up'
});
});
// ============================================
// SECTION 5: Release Quality
// ============================================
const qualitySection = form.addSubform('qualitySection', {
title: 'Update Quality',
isVisible: () => reactionSection.emojiRating('initialReaction')?.value() !== null
});
qualitySection.addRow(row => {
row.addStarRating('releaseQuality', {
label: 'How would you rate the overall quality of this release?',
maxStars: 5,
size: 'xl',
alignment: 'center',
showConfettiOnMax: true
});
});
qualitySection.addRow(row => {
row.addStarRating('communicationQuality', {
label: 'How clear was the release communication?',
tooltip: 'Were the release notes easy to understand?',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('updateProcess', {
label: 'How smooth was the update process?',
tooltip: 'Did everything work as expected after updating?',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
// ============================================
// SECTION 6: Missing Features & Suggestions
// ============================================
const suggestionsSection = form.addSubform('suggestionsSection', {
title: 'What\'s Missing?',
isVisible: () => qualitySection.starRating('releaseQuality')?.value() !== null
});
suggestionsSection.addRow(row => {
row.addRadioButton('missingFeature', {
label: 'Was there a feature you were hoping to see in this release?',
options: [
{ id: 'yes', name: 'Yes, I was expecting something' },
{ id: 'no', name: 'No, this release has what I needed' },
{ id: 'exceeded', name: 'This release exceeded my expectations!' }
],
orientation: 'vertical'
});
});
suggestionsSection.addSpacer();
suggestionsSection.addRow(row => {
row.addTextarea('missingFeatureDetails', {
label: 'What feature were you hoping to see?',
placeholder: 'Describe the feature you\'re waiting for...',
rows: 3,
autoExpand: true,
isVisible: () => suggestionsSection.radioButton('missingFeature')?.value() === 'yes'
});
});
suggestionsSection.addRow(row => {
row.addTextarea('exceededDetails', {
label: 'That\'s great to hear! What exceeded your expectations?',
placeholder: 'Tell us what surprised you...',
rows: 2,
autoExpand: true,
isVisible: () => suggestionsSection.radioButton('missingFeature')?.value() === 'exceeded'
});
});
// ============================================
// SECTION 7: Future Updates
// ============================================
const futureSection = form.addSubform('futureSection', {
title: 'Looking Ahead',
isVisible: () => qualitySection.starRating('releaseQuality')?.value() !== null
});
futureSection.addRow(row => {
row.addSuggestionChips('futureInterest', {
label: 'What would you like to see in future updates? (Select up to 3)',
suggestions: [
{ id: 'ai', name: 'AI Features' },
{ id: 'automation', name: 'More Automation' },
{ id: 'reporting', name: 'Better Reporting' },
{ id: 'api', name: 'API Improvements' },
{ id: 'mobile', name: 'Mobile Features' },
{ id: 'integrations', name: 'More Integrations' },
{ id: 'customization', name: 'Customization Options' },
{ id: 'security', name: 'Security Features' }
],
max: 3,
alignment: 'center'
});
});
futureSection.addRow(row => {
row.addRadioButton('updateFrequency', {
label: 'How often would you like to see updates?',
options: [
{ id: 'weekly', name: 'Weekly - Keep them coming!' },
{ id: 'biweekly', name: 'Every 2 weeks' },
{ id: 'monthly', name: 'Monthly - Current pace is good' },
{ id: 'quarterly', name: 'Quarterly - Prefer bigger updates' }
],
orientation: 'horizontal'
});
});
// ============================================
// SECTION 8: Summary
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Feedback Summary',
isVisible: () => qualitySection.starRating('releaseQuality')?.value() !== null
});
summarySection.addRow(row => {
row.addTextPanel('summaryDisplay', {
computedValue: () => {
const reaction = reactionSection.emojiRating('initialReaction')?.value();
const quality = qualitySection.starRating('releaseQuality')?.value();
const features = featuresSection.checkboxList('interestedFeatures')?.value() || [];
const topFeature = anticipatedSection.radioButton('topFeature')?.value();
const future = futureSection.suggestionChips('futureInterest')?.value() || [];
const moodLabels: Record<string, string> = {
'sad': 'Disappointed',
'down': 'Underwhelmed',
'neutral': 'Neutral',
'happy': 'Happy',
'excited': 'Excited!'
};
const featureLabels: Record<string, string> = {
'dark-mode': 'Dark Mode',
'keyboard-shortcuts': 'Keyboard Shortcuts',
'export-csv': 'CSV Export',
'collaboration': 'Collaboration',
'templates': 'Templates',
'mobile-app': 'Mobile App',
'integrations': 'Integrations',
'performance': 'Performance'
};
let emoji = '📋';
if (reaction === 'excited') emoji = '🎉';
else if (reaction === 'happy') emoji = '😊';
else if (reaction === 'neutral') emoji = '😐';
else if (reaction === 'down' || reaction === 'sad') emoji = '😟';
let summary = `${emoji} RELEASE FEEDBACK SUMMARY\n`;
summary += '═'.repeat(28) + '\n\n';
summary += `Reaction: ${moodLabels[reaction || ''] || 'Not provided'}\n`;
if (quality !== null && quality !== undefined) {
summary += `Quality: ${'★'.repeat(quality)}${'☆'.repeat(5 - quality)} (${quality}/5)\n`;
}
if (features.length > 0) {
summary += `\n✨ Interested in ${features.length} feature(s)\n`;
}
if (topFeature) {
summary += `🎯 Top pick: ${featureLabels[topFeature] || topFeature}\n`;
}
if (future.length > 0) {
summary += `\n🔮 Future requests: ${future.length} topic(s)`;
}
return summary;
},
customStyles: () => {
const reaction = reactionSection.emojiRating('initialReaction')?.value();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (reaction === 'excited' || reaction === 'happy') {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
}
if (reaction === 'neutral') {
return { ...baseStyles, backgroundColor: '#dbeafe', borderLeft: '4px solid #3b82f6' };
}
if (reaction === 'down' || reaction === 'sad') {
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
return { ...baseStyles, backgroundColor: '#f1f5f9', borderLeft: '4px solid #64748b' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Feedback',
isVisible: () => qualitySection.starRating('releaseQuality')?.value() !== null
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your input helps us shape the product roadmap. We read every response and use this feedback to prioritize what we build next.'
});
}