export function usabilityQuickSurvey(form: FormTs) {
// Quick Usability Check - System Usability Scale (SUS) Survey
// Demonstrates: MatrixQuestion (SUS), EmojiRating, Slider, computedValue (SUS score calculation), dynamic styling
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Quick Usability Check',
computedValue: () => 'Help us understand how easy our product is to use.',
customStyles: {
backgroundColor: '#8b5cf6',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: First Impression
// ============================================
const impressionSection = form.addSubform('impressionSection', {
title: 'Your First Impression'
});
impressionSection.addRow(row => {
row.addEmojiRating('firstImpression', {
label: 'How would you describe your overall experience using our product?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
impressionSection.addRow(row => {
row.addDropdown('experienceLevel', {
label: 'How long have you been using this product?',
options: [
{ id: 'first-time', name: 'First time today' },
{ id: 'few-days', name: 'A few days' },
{ id: 'few-weeks', name: 'A few weeks' },
{ id: 'few-months', name: 'A few months' },
{ id: 'year-plus', name: 'More than a year' }
],
placeholder: 'Select your experience level',
isRequired: true
}, '1fr');
row.addDropdown('taskCompleted', {
label: 'Were you able to complete your task?',
options: [
{ id: 'yes-easy', name: 'Yes, easily' },
{ id: 'yes-some-effort', name: 'Yes, with some effort' },
{ id: 'partially', name: 'Partially' },
{ id: 'no', name: 'No' }
],
placeholder: 'Select',
isRequired: true
}, '1fr');
});
// ============================================
// SECTION 2: System Usability Scale (SUS)
// ============================================
const susSection = form.addSubform('susSection', {
title: 'Usability Assessment (SUS)',
customStyles: { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' }
});
susSection.addRow(row => {
row.addTextPanel('susIntro', {
computedValue: () => 'Please rate how much you agree or disagree with each statement.',
customStyles: {
fontSize: '14px',
color: '#64748b',
marginBottom: '8px'
}
});
});
susSection.addRow(row => {
row.addMatrixQuestion('susQuestions', {
label: 'System Usability Scale',
rows: [
{ id: 'sus1', label: '1. I think that I would like to use this product frequently.', isRequired: true },
{ id: 'sus2', label: '2. I found the product unnecessarily complex.', isRequired: true },
{ id: 'sus3', label: '3. I thought the product was easy to use.', isRequired: true },
{ id: 'sus4', label: '4. I think I would need technical support to use this product.', isRequired: true },
{ id: 'sus5', label: '5. I found the various functions were well integrated.', isRequired: true },
{ id: 'sus6', label: '6. I thought there was too much inconsistency in this product.', isRequired: true },
{ id: 'sus7', label: '7. I imagine most people would learn to use this quickly.', isRequired: true },
{ id: 'sus8', label: '8. I found the product very cumbersome to use.', isRequired: true },
{ id: 'sus9', label: '9. I felt very confident using the product.', isRequired: true },
{ id: 'sus10', label: '10. I needed to learn a lot before I could use this product.', isRequired: true }
],
columns: [
{ id: '1', label: 'Strongly Disagree' },
{ id: '2', label: 'Disagree' },
{ id: '3', label: 'Neutral' },
{ id: '4', label: 'Agree' },
{ id: '5', label: 'Strongly Agree' }
],
striped: true,
fullWidth: true
});
});
// ============================================
// SECTION 3: Additional Feedback
// ============================================
const additionalSection = form.addSubform('additionalSection', {
title: 'Tell Us More',
isVisible: () => {
const matrix = susSection.matrixQuestion('susQuestions');
return matrix?.areAllRequiredRowsAnswered() ?? false;
}
});
additionalSection.addRow(row => {
row.addSlider('effortLevel', {
label: 'How much mental effort did you need to use the product?',
min: 1,
max: 10,
step: 1,
defaultValue: 5,
showValue: true,
unit: '/10'
}, '1fr');
row.addSlider('learningCurve', {
label: 'How steep was the learning curve?',
min: 1,
max: 10,
step: 1,
defaultValue: 5,
showValue: true,
unit: '/10'
}, '1fr');
});
additionalSection.addRow(row => {
row.addSuggestionChips('painPoints', {
label: 'What were the biggest pain points? (Select up to 3)',
suggestions: [
{ id: 'navigation', name: 'Hard to navigate' },
{ id: 'confusing', name: 'Confusing interface' },
{ id: 'slow', name: 'Too slow' },
{ id: 'features', name: 'Missing features' },
{ id: 'errors', name: 'Error messages' },
{ id: 'terminology', name: 'Unclear terminology' },
{ id: 'mobile', name: 'Mobile experience' },
{ id: 'none', name: 'No issues' }
],
max: 3,
alignment: 'center'
});
});
additionalSection.addSpacer();
additionalSection.addRow(row => {
row.addTextarea('improvements', {
label: () => {
const painPoints = additionalSection.suggestionChips('painPoints')?.value() || [];
if (painPoints.includes('none')) {
return 'What did you like most about the experience?';
}
return 'What would most improve your experience?';
},
placeholder: 'Share your thoughts...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 4: SUS Score & Summary
// ============================================
const scoreSection = form.addSubform('scoreSection', {
title: 'Your SUS Score',
isVisible: () => {
const matrix = susSection.matrixQuestion('susQuestions');
return matrix?.areAllRequiredRowsAnswered() ?? false;
},
customStyles: () => {
const score = calculateSUSScore();
if (score === null) return { padding: '16px', borderRadius: '8px' };
if (score >= 80) return { backgroundColor: '#d1fae5', padding: '16px', borderRadius: '8px' };
if (score >= 68) return { backgroundColor: '#dbeafe', padding: '16px', borderRadius: '8px' };
if (score >= 51) return { backgroundColor: '#fef3c7', padding: '16px', borderRadius: '8px' };
return { backgroundColor: '#fee2e2', padding: '16px', borderRadius: '8px' };
}
});
// Helper function to calculate SUS score
function calculateSUSScore(): number | null {
const matrix = susSection.matrixQuestion('susQuestions');
if (!matrix) return null;
const values = matrix.value();
if (!values) return null;
// Check if all questions are answered
const requiredIds = ['sus1', 'sus2', 'sus3', 'sus4', 'sus5', 'sus6', 'sus7', 'sus8', 'sus9', 'sus10'];
for (const id of requiredIds) {
if (!values[id]) return null;
}
let total = 0;
// Odd questions (1,3,5,7,9) - positive: score - 1
// Even questions (2,4,6,8,10) - negative: 5 - score
for (let i = 1; i <= 10; i++) {
const rawScore = parseInt(values[`sus${i}`] as string, 10);
if (isNaN(rawScore)) return null;
if (i % 2 === 1) {
// Odd questions (positive)
total += (rawScore - 1);
} else {
// Even questions (negative)
total += (5 - rawScore);
}
}
// Multiply by 2.5 to get score out of 100
return total * 2.5;
}
function getSUSGrade(score: number): string {
if (score >= 80.3) return 'A';
if (score >= 68) return 'B';
if (score >= 51) return 'C';
if (score >= 25) return 'D';
return 'F';
}
function getSUSInterpretation(score: number): string {
if (score >= 80.3) return 'Excellent! Users find the product highly usable.';
if (score >= 68) return 'Good usability, above average. Minor improvements possible.';
if (score >= 51) return 'OK, but there\'s room for improvement.';
if (score >= 25) return 'Below average. Consider addressing usability issues.';
return 'Poor usability. Significant improvements needed.';
}
scoreSection.addRow(row => {
row.addTextPanel('scoreDisplay', {
computedValue: () => {
const score = calculateSUSScore();
if (score === null) return 'Complete all questions to see your SUS score.';
const grade = getSUSGrade(score);
const interpretation = getSUSInterpretation(score);
let emoji = '';
if (score >= 80) emoji = '🎉';
else if (score >= 68) emoji = '👍';
else if (score >= 51) emoji = '😐';
else emoji = '⚠️';
let summary = `${emoji} SUS SCORE RESULTS\n`;
summary += `${'═'.repeat(28)}\n\n`;
summary += `📊 Score: ${score.toFixed(1)} / 100\n`;
summary += `📈 Grade: ${grade}\n\n`;
summary += `${interpretation}\n\n`;
summary += `${'─'.repeat(28)}\n`;
summary += `Note: Industry average is 68\n`;
summary += `Scores 80+ are considered excellent`;
return summary;
},
customStyles: () => {
const score = calculateSUSScore();
const baseStyles = {
padding: '16px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '14px'
};
if (score === null) {
return { ...baseStyles, backgroundColor: '#f1f5f9', color: '#64748b' };
}
if (score >= 80) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
}
if (score >= 68) {
return { ...baseStyles, backgroundColor: '#dbeafe', borderLeft: '4px solid #3b82f6' };
}
if (score >= 51) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
});
});
// ============================================
// SECTION 5: NPS Follow-up
// ============================================
const npsSection = form.addSubform('npsSection', {
title: 'Would You Recommend?',
isVisible: () => {
const matrix = susSection.matrixQuestion('susQuestions');
return matrix?.areAllRequiredRowsAnswered() ?? false;
}
});
npsSection.addRow(row => {
row.addRatingScale('recommendScore', {
preset: 'nps',
label: 'How likely are you to recommend this product to a colleague?',
showSegmentColors: true,
showCategoryLabel: true,
alignment: 'center'
});
});
npsSection.addRow(row => {
row.addTextarea('npsReason', {
label: () => {
const category = npsSection.ratingScale('recommendScore')?.npsCategory();
if (category === 'promoter') return 'What makes this product stand out?';
if (category === 'detractor') return 'What would need to change for you to recommend it?';
return 'What could we do to earn a higher score?';
},
placeholder: 'Your feedback helps us improve...',
rows: 2,
autoExpand: true,
isVisible: () => npsSection.ratingScale('recommendScore')?.value() !== null
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Usability Feedback',
isVisible: () => {
const matrix = susSection.matrixQuestion('susQuestions');
return matrix?.areAllRequiredRowsAnswered() ?? false;
}
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Your Feedback!',
message: 'Your usability insights help us create a better product experience. We review all feedback to identify and prioritize improvements.'
});
}