export function usabilityDetailedStudy(form: FormTs) {
// Detailed Usability Study - Comprehensive UX research form with task-based ratings
// Demonstrates: MatrixQuestion, StarRating, Slider, Multi-page, RatingScale (CES), dynamic labels, computed values
// ============================================
// HEADER
// ============================================
form.addRow(row => {
row.addTextPanel('header', {
label: 'Usability Study',
computedValue: () => 'Help us improve by sharing your experience with specific tasks.',
customStyles: {
backgroundColor: '#7c3aed',
color: 'white',
padding: '24px',
borderRadius: '12px',
textAlign: 'center'
}
});
});
// ============================================
// SECTION 1: Participant Information
// ============================================
const participantSection = form.addSubform('participantSection', {
title: 'About You',
customStyles: { backgroundColor: '#f8fafc', padding: '16px', borderRadius: '8px' }
});
participantSection.addRow(row => {
row.addDropdown('experienceLevel', {
label: 'How familiar are you with this type of product?',
options: [
{ id: 'novice', name: 'Novice - New to this type of product' },
{ id: 'intermediate', name: 'Intermediate - Some experience' },
{ id: 'experienced', name: 'Experienced - Regular user of similar products' },
{ id: 'expert', name: 'Expert - Professional/power user' }
],
placeholder: 'Select your experience level',
isRequired: true
}, '1fr');
row.addDropdown('deviceUsed', {
label: 'What device are you using?',
options: [
{ id: 'desktop', name: 'Desktop/Laptop' },
{ id: 'tablet', name: 'Tablet' },
{ id: 'mobile', name: 'Smartphone' }
],
placeholder: 'Select device',
isRequired: true
}, '1fr');
});
participantSection.addRow(row => {
row.addCheckbox('priorExperience', {
label: 'I have used this specific product before today'
});
});
// ============================================
// SECTION 2: Task-Based Evaluation
// ============================================
const tasksSection = form.addSubform('tasksSection', {
title: 'Task Evaluation',
isVisible: () => participantSection.dropdown('experienceLevel')?.value() !== null
});
tasksSection.addRow(row => {
row.addTextPanel('taskIntro', {
computedValue: () => 'For each task you attempted, please rate how it went. Be as honest as possible - your feedback helps us improve.',
customStyles: {
fontSize: '14px',
color: '#475569',
padding: '12px',
backgroundColor: '#f1f5f9',
borderRadius: '8px',
marginBottom: '16px'
}
});
});
// Task completion matrix
tasksSection.addRow(row => {
row.addMatrixQuestion('taskCompletion', {
label: 'Were you able to complete each task?',
rows: [
{ id: 'task1', label: 'Task 1: Find and view product details', isRequired: true },
{ id: 'task2', label: 'Task 2: Add item to cart', isRequired: true },
{ id: 'task3', label: 'Task 3: Complete checkout process', isRequired: true },
{ id: 'task4', label: 'Task 4: Find order history', isRequired: false },
{ id: 'task5', label: 'Task 5: Contact customer support', isRequired: false }
],
columns: [
{ id: 'success', label: 'Completed easily' },
{ id: 'struggled', label: 'Completed with difficulty' },
{ id: 'partial', label: 'Partially completed' },
{ id: 'failed', label: 'Could not complete' },
{ id: 'skipped', label: 'Did not attempt' }
],
striped: true,
fullWidth: true
});
});
// Task difficulty ratings
const difficultySection = tasksSection.addSubform('difficultySection', {
title: 'Task Difficulty',
isVisible: () => {
const matrix = tasksSection.matrixQuestion('taskCompletion');
return matrix?.isRowAnswered('task1') ?? false;
},
customStyles: { marginTop: '16px' }
});
difficultySection.addRow(row => {
row.addSlider('task1Difficulty', {
label: 'Task 1: Find and view product details',
min: 1,
max: 7,
step: 1,
defaultValue: 4,
showValue: true
}, '1fr');
row.addSlider('task2Difficulty', {
label: 'Task 2: Add item to cart',
min: 1,
max: 7,
step: 1,
defaultValue: 4,
showValue: true
}, '1fr');
});
difficultySection.addRow(row => {
row.addSlider('task3Difficulty', {
label: 'Task 3: Complete checkout process',
min: 1,
max: 7,
step: 1,
defaultValue: 4,
showValue: true
}, '1fr');
row.addSlider('task4Difficulty', {
label: 'Task 4: Find order history',
min: 1,
max: 7,
step: 1,
defaultValue: 4,
showValue: true,
isVisible: () => {
const val = tasksSection.matrixQuestion('taskCompletion')?.getRowValue('task4');
return val !== 'skipped' && val !== undefined;
}
}, '1fr');
});
difficultySection.addRow(row => {
row.addTextPanel('difficultyScale', {
computedValue: () => '1 = Very Easy | 4 = Neutral | 7 = Very Difficult',
customStyles: {
fontSize: '12px',
color: '#64748b',
textAlign: 'center',
marginTop: '8px'
}
});
});
// ============================================
// SECTION 3: Most Problematic Task
// ============================================
const problemSection = form.addSubform('problemSection', {
title: 'Biggest Challenges',
isVisible: () => {
const matrix = tasksSection.matrixQuestion('taskCompletion');
return matrix?.isRowAnswered('task1') ?? false;
}
});
problemSection.addRow(row => {
row.addRadioButton('hardestTask', {
label: 'Which task was the most difficult?',
options: [
{ id: 'task1', name: 'Task 1: Find and view product details' },
{ id: 'task2', name: 'Task 2: Add item to cart' },
{ id: 'task3', name: 'Task 3: Complete checkout process' },
{ id: 'task4', name: 'Task 4: Find order history' },
{ id: 'task5', name: 'Task 5: Contact customer support' },
{ id: 'none', name: 'None - all tasks were easy' }
],
orientation: 'vertical'
});
});
problemSection.addSpacer();
problemSection.addRow(row => {
row.addTextarea('taskObstacles', {
label: () => {
const hardest = problemSection.radioButton('hardestTask')?.value();
if (hardest === 'none') {
return 'What made the tasks easy to complete?';
}
return 'What made this task difficult? Please describe any obstacles you encountered.';
},
placeholder: 'Describe what happened...',
rows: 4,
autoExpand: true,
isVisible: () => problemSection.radioButton('hardestTask')?.value() !== null
});
});
// ============================================
// SECTION 4: Navigation & Information Architecture
// ============================================
const navigationSection = form.addSubform('navigationSection', {
title: 'Navigation & Findability',
isVisible: () => {
const matrix = tasksSection.matrixQuestion('taskCompletion');
return matrix?.isRowAnswered('task1') ?? false;
}
});
navigationSection.addRow(row => {
row.addMatrixQuestion('navigationRatings', {
label: 'Rate your experience with navigation:',
rows: [
{ id: 'findability', label: 'Easy to find what I was looking for', isRequired: true },
{ id: 'menuStructure', label: 'Menu structure was logical', isRequired: true },
{ id: 'labels', label: 'Labels and icons were clear', isRequired: true },
{ id: 'backtrack', label: 'Easy to go back or undo actions', isRequired: false },
{ id: 'orientation', label: 'Always knew where I was in the product', isRequired: false }
],
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
});
});
navigationSection.addRow(row => {
row.addThumbRating('searchUsed', {
label: 'Did you use search functionality?',
showLabels: true,
upLabel: 'Yes',
downLabel: 'No',
size: 'md'
}, '1fr');
row.addStarRating('searchQuality', {
label: 'How useful was the search?',
maxStars: 5,
size: 'lg',
alignment: 'center',
isVisible: () => navigationSection.thumbRating('searchUsed')?.value() === 'up'
}, '1fr');
});
// ============================================
// SECTION 5: Visual Design & Clarity
// ============================================
const visualSection = form.addSubform('visualSection', {
title: 'Visual Design & Clarity',
isVisible: () => {
const matrix = tasksSection.matrixQuestion('taskCompletion');
return matrix?.isRowAnswered('task1') ?? false;
}
});
visualSection.addRow(row => {
row.addStarRating('visualAppeal', {
label: 'Visual Appeal',
tooltip: 'How attractive and professional does the interface look?',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('readability', {
label: 'Readability',
tooltip: 'How easy is it to read text and understand content?',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
visualSection.addRow(row => {
row.addStarRating('consistency', {
label: 'Consistency',
tooltip: 'Does the design feel consistent throughout?',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
row.addStarRating('informationClarity', {
label: 'Information Clarity',
tooltip: 'Is information presented clearly and organized well?',
maxStars: 5,
size: 'lg',
alignment: 'center'
}, '1fr');
});
// ============================================
// SECTION 6: System Usability Scale (SUS)
// ============================================
const susSection = form.addSubform('susSection', {
title: 'System Usability Scale (SUS)',
isVisible: () => {
const matrix = tasksSection.matrixQuestion('taskCompletion');
return matrix?.isRowAnswered('task1') ?? false;
},
customStyles: { backgroundColor: '#faf5ff', padding: '16px', borderRadius: '8px' }
});
susSection.addRow(row => {
row.addTextPanel('susIntro', {
computedValue: () => 'Please rate how much you agree with each statement based on your experience.',
customStyles: {
fontSize: '14px',
color: '#6b21a8',
marginBottom: '12px'
}
});
});
susSection.addRow(row => {
row.addMatrixQuestion('susQuestions', {
label: '',
rows: [
{ id: 'sus1', label: '1. 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 would need technical support to use this product.', isRequired: true },
{ id: 'sus5', label: '5. I found the various functions well integrated.', isRequired: true },
{ id: 'sus6', label: '6. I thought there was too much inconsistency.', isRequired: true },
{ id: 'sus7', label: '7. Most people would learn to use this quickly.', isRequired: true },
{ id: 'sus8', label: '8. I found the product cumbersome to use.', isRequired: true },
{ id: 'sus9', label: '9. I felt confident using the product.', isRequired: true },
{ id: 'sus10', label: '10. I needed to learn a lot before getting started.', 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
});
});
// SUS Score calculation helper
function calculateSUSScore(): number | null {
const matrix = susSection.matrixQuestion('susQuestions');
if (!matrix) return null;
const values = matrix.value();
if (!values) return null;
const ids = ['sus1', 'sus2', 'sus3', 'sus4', 'sus5', 'sus6', 'sus7', 'sus8', 'sus9', 'sus10'];
for (const id of ids) {
if (!values[id]) return null;
}
let total = 0;
for (let i = 1; i <= 10; i++) {
const raw = parseInt(values[`sus${i}`] as string, 10);
if (isNaN(raw)) return null;
total += i % 2 === 1 ? (raw - 1) : (5 - raw);
}
return total * 2.5;
}
function getSUSGrade(score: number): string {
if (score >= 80.3) return 'A (Excellent)';
if (score >= 68) return 'B (Good)';
if (score >= 51) return 'C (Average)';
if (score >= 25) return 'D (Below Average)';
return 'F (Poor)';
}
// ============================================
// SECTION 7: Overall Experience
// ============================================
const overallSection = form.addSubform('overallSection', {
title: 'Overall Experience',
isVisible: () => susSection.matrixQuestion('susQuestions')?.areAllRequiredRowsAnswered() ?? false
});
overallSection.addRow(row => {
row.addRatingScale('overallEffort', {
preset: 'ces',
label: 'Overall, how easy was it to use this product?',
lowLabel: 'Very Difficult',
highLabel: 'Very Easy',
alignment: 'center'
});
});
overallSection.addRow(row => {
row.addEmojiRating('overallMood', {
label: 'How would you describe your overall experience?',
preset: 'satisfaction',
size: 'lg',
showLabels: true,
alignment: 'center'
});
});
overallSection.addRow(row => {
row.addRatingScale('recommendScore', {
preset: 'nps',
label: 'How likely are you to recommend this product to others?',
showSegmentColors: true,
showCategoryLabel: true,
alignment: 'center'
});
});
// ============================================
// SECTION 8: Open Feedback
// ============================================
const feedbackSection = form.addSubform('feedbackSection', {
title: 'Additional Feedback',
isVisible: () => susSection.matrixQuestion('susQuestions')?.areAllRequiredRowsAnswered() ?? false
});
feedbackSection.addRow(row => {
row.addSuggestionChips('topIssues', {
label: 'What were the biggest usability issues? (Select up to 3)',
suggestions: [
{ id: 'confusing', name: 'Confusing layout' },
{ id: 'slow', name: 'Too slow' },
{ id: 'errors', name: 'Error messages unclear' },
{ id: 'navigation', name: 'Hard to navigate' },
{ id: 'terminology', name: 'Unclear labels/terms' },
{ id: 'feedback', name: 'Lack of system feedback' },
{ id: 'mobile', name: 'Mobile experience' },
{ id: 'none', name: 'No major issues' }
],
max: 3,
alignment: 'center'
});
});
feedbackSection.addSpacer();
feedbackSection.addRow(row => {
row.addTextarea('likedMost', {
label: 'What did you like most about the product?',
placeholder: 'Share what worked well...',
rows: 3,
autoExpand: true
});
});
feedbackSection.addRow(row => {
row.addTextarea('improvements', {
label: 'What would you change or improve?',
placeholder: 'Share your suggestions...',
rows: 3,
autoExpand: true
});
});
// ============================================
// SECTION 9: Summary & Scores
// ============================================
const summarySection = form.addSubform('summarySection', {
title: 'Study Summary',
isVisible: () => susSection.matrixQuestion('susQuestions')?.areAllRequiredRowsAnswered() ?? false
});
summarySection.addRow(row => {
row.addTextPanel('summaryDisplay', {
computedValue: () => {
const susScore = calculateSUSScore();
const effort = overallSection.ratingScale('overallEffort')?.value();
const mood = overallSection.emojiRating('overallMood')?.value();
const nps = overallSection.ratingScale('recommendScore')?.value();
const npsCategory = overallSection.ratingScale('recommendScore')?.npsCategory();
const issues = feedbackSection.suggestionChips('topIssues')?.value() || [];
const taskMatrix = tasksSection.matrixQuestion('taskCompletion')?.value();
let completedCount = 0;
let failedCount = 0;
if (taskMatrix) {
Object.values(taskMatrix).forEach(val => {
if (val === 'success' || val === 'struggled') completedCount++;
else if (val === 'failed') failedCount++;
});
}
const moodLabels: Record<string, string> = {
'very-bad': 'Very Frustrated',
'bad': 'Frustrated',
'neutral': 'Neutral',
'good': 'Satisfied',
'excellent': 'Very Satisfied'
};
let summary = '📊 USABILITY STUDY SUMMARY\n';
summary += '═'.repeat(30) + '\n\n';
if (susScore !== null) {
summary += `🎯 SUS Score: ${susScore.toFixed(1)}/100\n`;
summary += ` Grade: ${getSUSGrade(susScore)}\n\n`;
}
summary += `✅ Tasks completed: ${completedCount}\n`;
if (failedCount > 0) {
summary += `❌ Tasks failed: ${failedCount}\n`;
}
if (effort !== null && effort !== undefined) {
summary += `\n💪 Effort Level: ${effort}/7\n`;
}
if (mood) {
summary += `😊 Experience: ${moodLabels[mood] || mood}\n`;
}
if (nps !== null && nps !== undefined && npsCategory) {
const catLabels: Record<string, string> = {
'promoter': 'Promoter',
'passive': 'Passive',
'detractor': 'Detractor'
};
summary += `\n📈 NPS: ${nps}/10 (${catLabels[npsCategory]})`;
}
if (issues.length > 0 && !issues.includes('none')) {
summary += `\n\n⚠️ Top Issues: ${issues.length} identified`;
}
return summary;
},
customStyles: () => {
const susScore = calculateSUSScore();
const baseStyles = {
padding: '20px',
borderRadius: '8px',
whiteSpace: 'pre-wrap',
fontFamily: 'monospace',
fontSize: '13px'
};
if (susScore === null) {
return { ...baseStyles, backgroundColor: '#f1f5f9' };
}
if (susScore >= 80) {
return { ...baseStyles, backgroundColor: '#d1fae5', borderLeft: '4px solid #10b981' };
}
if (susScore >= 68) {
return { ...baseStyles, backgroundColor: '#dbeafe', borderLeft: '4px solid #3b82f6' };
}
if (susScore >= 51) {
return { ...baseStyles, backgroundColor: '#fef3c7', borderLeft: '4px solid #f59e0b' };
}
return { ...baseStyles, backgroundColor: '#fee2e2', borderLeft: '4px solid #ef4444' };
}
});
});
// ============================================
// FORM CONFIGURATION
// ============================================
form.configureSubmitButton({
label: 'Submit Study Results',
isVisible: () => susSection.matrixQuestion('susQuestions')?.areAllRequiredRowsAnswered() ?? false
});
form.configureCompletionScreen({
type: 'text',
title: 'Thank You for Participating!',
message: 'Your detailed feedback is invaluable for improving the product experience. Our UX team will carefully review all observations and use them to prioritize improvements.'
});
}