@explorer02/cfm-survey-sdk 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +94 -83
- package/dist/cli/index.mjs +94 -83
- package/package.json +1 -1
- package/templates/docs/00-integration/client-lib-folder.md +1 -0
- package/templates/docs/00-integration/wizard-chrome-contract.md +2 -1
- package/templates/docs/00-integration/wizard-preview-build-guide.md +17 -0
- package/templates/docs/01-components/03-rating-scale.md +8 -3
- package/templates/docs/02-reference/value-derivation.md +2 -0
- package/templates/docs/03-ui-specs/01-rating.md +15 -1
- package/templates/docs/templates/CsatMatrixScale.tsx +18 -24
- package/templates/docs/templates/CustomSliderTrack.tsx +5 -3
- package/templates/docs/templates/FileUploadScale.tsx +143 -18
- package/templates/docs/templates/Header.tsx +1 -0
- package/templates/docs/templates/HeatmapScale.tsx +11 -2
- package/templates/docs/templates/LanguageSelector.tsx +42 -19
- package/templates/docs/templates/LikertMatrixScale.tsx +43 -33
- package/templates/docs/templates/MatrixDropdown.tsx +12 -11
- package/templates/docs/templates/Question.tsx +109 -44
- package/templates/docs/templates/RankOrderScale.tsx +22 -5
- package/templates/docs/templates/RatingScale.tsx +77 -39
- package/templates/docs/templates/SliderMatrixScale.tsx +44 -16
- package/templates/docs/templates/selectionStyles.ts +90 -2
- package/templates/docs/templates/surveyUiIcons.tsx +2 -2
- package/templates/docs/templates/surveyUiScaleUtils.ts +52 -5
- package/templates/docs/templates/uiConfig.ts +56 -0
- package/templates/preview-harness/preview-bridge.inline.js +44 -0
- package/templates/preview-harness/previewPages.js +76 -51
- package/templates/preview-harness/previewPages.ts +7 -34
- package/templates/preview-harness/vite-app/src/PreviewConfigContext.tsx +7 -0
- package/templates/preview-harness/vite-app/src/QuestionPreview.tsx +59 -30
- package/templates/preview-harness/vite-app/src/SurveyPagePreview.tsx +36 -8
- package/templates/preview-harness/vite-app/src/fixtures/questions.ts +182 -82
- package/templates/previewBridge.ts +33 -0
- package/templates/survey-theme.css +13 -4
- package/templates/wizard-dist/assets/{PreviewMock-Bax7oRAL.js → PreviewMock-DbbLpHdF.js} +1 -1
- package/templates/wizard-dist/assets/TypePanel-DQbV2iCf.js +1 -0
- package/templates/wizard-dist/assets/index-CY7WMJ93.js +34 -0
- package/templates/wizard-dist/index.html +1 -1
- package/templates/wizard-dist/assets/TypePanel-D2t4FPSd.js +0 -1
- package/templates/wizard-dist/assets/index-c5lka74l.js +0 -34
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/** Static wizard preview pages — layout matches previewPages.ts; tokens via --cfm-* + preview-bridge. */
|
|
3
4
|
const sharedStyles = `
|
|
4
5
|
.cfm-header { height:var(--cfm-header-height); background:var(--cfm-header-bg); border-bottom:1px solid var(--cfm-header-border); display:flex; align-items:center; padding:0 var(--cfm-header-padding-x); box-shadow:0 2px 8px rgba(0,0,0,0.06); }
|
|
5
|
-
.cfm-header-logo { width:var(--cfm-header-logo-width); height:var(--cfm-header-logo-height); object-fit:contain; padding:var(--cfm-header-logo-padding); background:transparent; }
|
|
6
|
+
.cfm-header-logo { width:var(--cfm-header-logo-width); height:var(--cfm-header-logo-height); max-height:calc(var(--cfm-header-height, 120px) - 8px); object-fit:contain; padding:var(--cfm-header-logo-padding); background:transparent; }
|
|
6
7
|
.cfm-header-company { font-size:var(--cfm-header-company-size); font-weight:var(--cfm-header-company-weight); color:var(--cfm-header-company-color); margin-left:16px; }
|
|
7
8
|
.cfm-footer { background:var(--cfm-footer-bg); color:var(--cfm-footer-text); padding:var(--cfm-footer-padding-y) var(--cfm-footer-padding-x); display:flex; flex-wrap:wrap; gap:16px; justify-content:space-between; align-items:flex-end; }
|
|
8
9
|
.cfm-footer-links { display:flex; gap:24px; flex-wrap:wrap; }
|
|
@@ -10,91 +11,115 @@ const sharedStyles = `
|
|
|
10
11
|
.cfm-progress { height:var(--cfm-progress-height); background:var(--cfm-progress-track); border-radius:999px; overflow:hidden; margin:var(--cfm-sticky-pt) 0 var(--cfm-sticky-pb); }
|
|
11
12
|
.cfm-progress-fill { height:100%; width:45%; background:var(--cfm-progress-fill); border-radius:999px; }
|
|
12
13
|
.cfm-mcq-option { border:2px solid #e5e7eb; border-radius:var(--cfm-mcq-border-radius); padding:var(--cfm-mcq-card-padding); margin-bottom:var(--cfm-mcq-option-gap); display:flex; align-items:center; gap:8px; }
|
|
13
|
-
.cfm-mcq-option.selected { border-color:var(--cfm-
|
|
14
|
-
.cfm-nps-row { display:flex; gap:var(--cfm-nps-cell-gap); flex-wrap:wrap; }
|
|
15
|
-
.cfm-nps-cell { width:var(--cfm-nps-cell-size); height:var(--cfm-nps-cell-size); border-radius:var(--cfm-border-radius); background:var(--cfm-nps-track-bar,#f2f2f2); display:flex; align-items:center; justify-content:center; font-size:14px; box-sizing:border-box; }
|
|
16
|
-
.cfm-nps-cell.selected { border:2px solid var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); color:#fff; }
|
|
14
|
+
.cfm-mcq-option.selected { border-color:var(--cfm-input-focus-ring); background:var(--cfm-mcq-selected-bg); }
|
|
17
15
|
.cfm-hint-row { display:flex; justify-content:space-between; font-size:12px; font-weight:600; margin-bottom:8px; }
|
|
18
16
|
.cfm-hint-min, .cfm-hint-max { color:var(--cfm-hint-label-color,#6b7280); background:var(--cfm-hint-label-bg,transparent); padding:2px 4px; border-radius:4px; }
|
|
19
|
-
.cfm-
|
|
17
|
+
.cfm-nps-badges { display:grid; grid-template-columns:repeat(11,minmax(0,1fr)); gap:var(--cfm-nps-cell-gap,2px); margin-bottom:8px; }
|
|
18
|
+
.cfm-nps-badge { width:var(--cfm-nps-cell-size,24px); height:var(--cfm-nps-cell-size,24px); margin:0 auto; border-radius:3px; font-size:10px; font-weight:700; color:#fff; display:flex; align-items:center; justify-content:center; box-sizing:border-box; }
|
|
19
|
+
.cfm-nps-badge.selected { border:2px solid var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); }
|
|
20
|
+
.cfm-nps-track { background:var(--cfm-nps-track-bar,#f2f2f2); border-radius:6px; padding:8px 4px; }
|
|
21
|
+
.cfm-nps-row { display:grid; grid-template-columns:repeat(11,minmax(0,1fr)); gap:var(--cfm-nps-cell-gap,2px); }
|
|
22
|
+
.cfm-nps-radio { width:var(--cfm-nps-cell-size,32px); height:var(--cfm-nps-cell-size,32px); margin:0 auto; border-radius:50%; border:2px solid #d1d5db; background:#fff; box-sizing:border-box; display:flex; align-items:center; justify-content:center; }
|
|
23
|
+
.cfm-nps-radio.selected { border-color:var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); }
|
|
24
|
+
.cfm-nps-radio.selected::after { content:''; width:33%; height:33%; border-radius:50%; background:var(--cfm-input-focus-ring); }
|
|
20
25
|
.cfm-matrix-row { display:flex; align-items:center; padding:8px 0; background:var(--cfm-row-band); margin-bottom:4px; }
|
|
21
|
-
.cfm-matrix-label { width:var(--cfm-matrix-row-width); flex-shrink:0; padding:0 16px; font-size:14px; font-weight:500; }
|
|
22
|
-
.cfm-matrix-cells { display:flex; gap:8px; flex:1; justify-content:center; }
|
|
26
|
+
.cfm-matrix-label { width:var(--cfm-matrix-row-width,180px); flex-shrink:0; padding:0 16px; font-size:14px; font-weight:500; box-sizing:border-box; }
|
|
27
|
+
.cfm-matrix-cells { display:flex; gap:8px; flex:1; justify-content:center; align-items:center; }
|
|
28
|
+
.cfm-matrix-col-label { font-size:13px; font-weight:500; text-align:center; color:var(--cfm-csat-column-label-color,var(--cfm-matrix-column-label-color,#4b5563)); background:var(--cfm-csat-column-label-bg,var(--cfm-matrix-column-label-bg,transparent)); padding:2px 6px; border-radius:4px; }
|
|
23
29
|
.cfm-matrix-cell { width:var(--cfm-csat-cell-size,18px); height:var(--cfm-csat-cell-size,18px); border-radius:50%; border:2px solid #d1d5db; box-sizing:border-box; }
|
|
24
30
|
.cfm-matrix-cell.selected { border-color:var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); }
|
|
25
|
-
.cfm-emoji { font-size:var(--cfm-csat-emoji-size); opacity:var(--cfm-csat-unselected-opacity); }
|
|
26
|
-
.cfm-emoji.selected { opacity:1; outline:2px solid var(--cfm-input-focus-ring); border-radius:8px;
|
|
27
|
-
.cfm-star { color:var(--cfm-input-focus-ring); font-size:var(--cfm-csat-emoji-size,24px); opacity:var(--cfm-csat-unselected-opacity); }
|
|
31
|
+
.cfm-emoji { font-size:var(--cfm-csat-emoji-size,28px); opacity:var(--cfm-csat-unselected-opacity,0.5); line-height:1; }
|
|
32
|
+
.cfm-emoji.selected { opacity:1; outline:2px solid var(--cfm-input-focus-ring); border-radius:8px; }
|
|
33
|
+
.cfm-star { color:var(--cfm-input-focus-ring); font-size:var(--cfm-csat-emoji-size,24px); opacity:var(--cfm-csat-unselected-opacity,0.5); }
|
|
28
34
|
.cfm-star.selected { opacity:1; color:var(--cfm-matrix-selected); }
|
|
29
|
-
.cfm-badge { width:40px; height:40px; border-radius:8px;
|
|
35
|
+
.cfm-badge { width:40px; height:40px; border-radius:8px; color:#fff; display:flex; align-items:center; justify-content:center; font-weight:600; border:1px solid #d1d5db; box-sizing:border-box; }
|
|
30
36
|
.cfm-badge.selected { border:2px solid var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); color:#fff; }
|
|
31
|
-
.cfm-slider-track { height:8px; background:var(--cfm-slider-track); border-radius:4px; position:relative; margin:24px 0; }
|
|
32
|
-
.cfm-slider-thumb { width:20px; height:20px; background:var(--cfm-slider-thumb); border-radius:50%; position:absolute; top:-6px; left:60%; }
|
|
33
|
-
.cfm-tick { width:var(--cfm-slider-tick-size); height:var(--cfm-slider-tick-size); background:var(--cfm-slider-tick); border-radius:4px; font-size:11px; display:flex; align-items:center; justify-content:center; color:
|
|
34
|
-
.cfm-
|
|
37
|
+
.cfm-slider-track { height:8px; background:var(--cfm-slider-track,#e5e7eb); border-radius:4px; position:relative; margin:24px 0; }
|
|
38
|
+
.cfm-slider-thumb { width:20px; height:20px; background:var(--cfm-slider-thumb,var(--cfm-input-focus-ring)); border-radius:50%; position:absolute; top:-6px; left:60%; border:2px solid var(--cfm-input-focus-ring); box-sizing:border-box; }
|
|
39
|
+
.cfm-tick { min-width:var(--cfm-slider-tick-size,24px); height:var(--cfm-slider-tick-size,24px); background:var(--cfm-slider-tick,#6b7280); border-radius:4px; font-size:11px; display:flex; align-items:center; justify-content:center; color:#fff; padding:0 4px; }
|
|
40
|
+
.cfm-slider-tick-label { font-size:12px; font-weight:500; color:var(--cfm-slider-tick-label-color,#4b5563); background:var(--cfm-slider-tick-label-bg,transparent); padding:2px 4px; border-radius:4px; }
|
|
41
|
+
.cfm-dropzone { border-width:2px; border-style:var(--cfm-upload-border-style,dashed); border-color:var(--cfm-upload-border-color,#d1d5db); border-radius:var(--cfm-border-radius,12px); padding:var(--cfm-upload-padding,24px); background:var(--cfm-upload-fill,#f9fafb); text-align:center; color:var(--cfm-text); }
|
|
35
42
|
.cfm-input { width:100%; height:var(--cfm-input-height); border:1px solid var(--cfm-input-border); border-radius:var(--cfm-input-radius); padding:0 var(--cfm-input-padding); font-family:inherit; box-sizing:border-box; }
|
|
36
|
-
.cfm-
|
|
37
|
-
.cfm-rank-
|
|
38
|
-
.cfm-
|
|
39
|
-
.cfm-
|
|
43
|
+
.cfm-input:focus { outline:2px solid var(--cfm-input-focus-ring); }
|
|
44
|
+
.cfm-rank-item { background:var(--cfm-rank-item-bg,#fff); padding:var(--cfm-rank-item-padding,12px 16px); margin-bottom:var(--cfm-rank-item-gap,8px); border-radius:var(--cfm-border-radius,8px); display:flex; align-items:center; gap:12px; }
|
|
45
|
+
.cfm-rank-badge { background:var(--cfm-rank-badge,var(--cfm-primary)); color:#fff; width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:12px; flex-shrink:0; }
|
|
46
|
+
.cfm-handle { color:var(--cfm-rank-handle,#9ca3af); cursor:grab; }
|
|
47
|
+
.cfm-rank-select { border-color:var(--cfm-rank-select-border,#d1d5db) !important; }
|
|
48
|
+
.cfm-pin { width:var(--cfm-heatmap-pin-size,16px); height:var(--cfm-heatmap-pin-size,16px); background:var(--cfm-heatmap-pin,#f97316); border:2px solid var(--cfm-heatmap-pin-border,#fff); border-radius:50%; position:absolute; box-sizing:border-box; }
|
|
40
49
|
.cfm-media { max-width:var(--cfm-media-max-width); border-radius:var(--cfm-media-radius); background:#e5e7eb; height:200px; display:flex; align-items:center; justify-content:center; }
|
|
41
50
|
.cfm-btn-primary { background:var(--cfm-primary); color:var(--cfm-button-text); border:none; border-radius:var(--cfm-border-radius); padding:10px 20px; }
|
|
42
51
|
.cfm-btn-back { background:transparent; color:var(--cfm-primary); border:1px solid var(--cfm-primary); border-radius:var(--cfm-border-radius); padding:10px 20px; }
|
|
43
52
|
`;
|
|
44
53
|
|
|
54
|
+
const TRAFFIC = ['#ef4444', '#f97316', '#eab308', '#84cc16', '#22c55e', '#14b8a6', '#06b6d4', '#3b82f6', '#6366f1', '#8b5cf6', '#a855f7'];
|
|
55
|
+
|
|
45
56
|
function cells(n) {
|
|
46
57
|
return Array.from({ length: n }, (_, i) =>
|
|
47
58
|
`<div class="cfm-matrix-cell${i === 2 ? ' selected' : ''}"></div>`,
|
|
48
59
|
).join('');
|
|
49
60
|
}
|
|
50
61
|
|
|
51
|
-
function
|
|
52
|
-
return
|
|
62
|
+
function colLabels(n) {
|
|
63
|
+
return Array.from({ length: n }, (_, i) => `<span class="cfm-matrix-col-label">${i + 1}</span>`).join('');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function matrixPreview(label, mode) {
|
|
67
|
+
if (mode === 'emoji') {
|
|
68
|
+
return `<div class="cfm-matrix-row"><div class="cfm-matrix-label">${label}</div><div class="cfm-matrix-cells"><span class="cfm-emoji">😞</span><span class="cfm-emoji selected">🙂</span><span class="cfm-emoji">😊</span></div></div>`;
|
|
69
|
+
}
|
|
70
|
+
return `<div class="cfm-matrix-row" style="background:transparent;margin-bottom:4px"><div class="cfm-matrix-label"></div><div class="cfm-matrix-cells">${colLabels(5)}</div></div>
|
|
71
|
+
<div class="cfm-matrix-row"><div class="cfm-matrix-label">${label}</div><div class="cfm-matrix-cells">${cells(5)}</div></div>`;
|
|
53
72
|
}
|
|
54
73
|
|
|
55
|
-
function
|
|
56
|
-
|
|
74
|
+
function npsPreview() {
|
|
75
|
+
const badges = Array.from({ length: 11 }, (_, i) =>
|
|
76
|
+
`<div class="cfm-nps-badge${i === 8 ? ' selected' : ''}" data-cfm-number-badge="${i}">${i}</div>`,
|
|
77
|
+
).join('');
|
|
78
|
+
const radios = Array.from({ length: 11 }, (_, i) =>
|
|
79
|
+
`<div class="cfm-nps-radio${i === 8 ? ' selected' : ''}"></div>`,
|
|
80
|
+
).join('');
|
|
81
|
+
return `<p style="font-weight:600;margin-bottom:8px">How likely are you to recommend us?</p>
|
|
82
|
+
<div class="cfm-hint-row"><span class="cfm-hint-min" data-cfm-hint-min>Not likely</span><span class="cfm-hint-max" data-cfm-hint-max>Very likely</span></div>
|
|
83
|
+
<div class="cfm-nps-badges">${badges}</div>
|
|
84
|
+
<div class="cfm-nps-track"><div class="cfm-nps-row">${radios}</div></div>`;
|
|
57
85
|
}
|
|
58
86
|
|
|
59
87
|
const npsCells = Array.from({ length: 11 }, (_, i) =>
|
|
60
|
-
`<div class="cfm-nps-
|
|
88
|
+
`<div class="cfm-nps-radio${i === 8 ? ' selected' : ''}"></div>`,
|
|
61
89
|
).join('');
|
|
62
90
|
|
|
63
91
|
const PREVIEW_PAGE_DEFS = [
|
|
64
92
|
{ key: 'header', title: 'Header', body: `<header class="cfm-header"><img data-cfm-logo class="cfm-header-logo" src="" alt="Logo" style="display:none" /><span data-cfm-company class="cfm-header-company">Company Name</span></header>` },
|
|
65
93
|
{ key: 'footer', title: 'Footer', body: `<footer class="cfm-footer"><div><img data-cfm-logo style="width:var(--cfm-footer-logo-width);height:var(--cfm-footer-logo-height);object-fit:contain;display:none" src="" alt="" /><p data-cfm-copyright style="font-size:12px;margin-top:8px">© Company</p></div><nav data-cfm-footer-links class="cfm-footer-links"></nav></footer>` },
|
|
66
|
-
{ key: '
|
|
67
|
-
{ key: '
|
|
68
|
-
{ key: 'intro', title: 'Intro', body: `<h1 data-cfm-survey-title style="font-size:28px;font-weight:var(--cfm-heading-weight)">Welcome</h1><p style="margin:16px 0;color:#6b7280">Please share your feedback.</p><button class="cfm-btn-primary">Start Survey</button>` },
|
|
69
|
-
{ key: 'end', title: 'End', body: `<h1 style="font-size:28px;font-weight:var(--cfm-heading-weight)">Thank you!</h1><p data-cfm-thank-you style="margin:16px 0">Thank you for your feedback.</p>` },
|
|
70
|
-
{ key: 'MCQ_single', title: 'MCQ Single', body: `<p style="font-weight:600;margin-bottom:16px">1. Select one option</p><div data-cfm-mcq-style="outlined"><div class="cfm-mcq-option selected"><span>◉</span> Option A</div><div class="cfm-mcq-option"><span>○</span> Option B</div></div>` },
|
|
94
|
+
{ key: 'survey_page', title: 'Survey Page', body: `<header class="cfm-header"><img data-cfm-logo class="cfm-header-logo" src="" alt="" style="display:none" /><span data-cfm-company class="cfm-header-company">Company</span></header><div data-cfm-progress class="cfm-progress"><div class="cfm-progress-fill" style="width:35%"></div></div><div data-cfm-language style="text-align:right;margin:16px 0"><select class="cfm-input" style="width:auto"><option>English</option><option>Deutsch</option></select></div><p style="font-weight:600"><span data-cfm-question-number>1.</span> Sample question <span data-cfm-required style="color:red">*</span></p><div class="cfm-mcq-option selected"><span>◉</span> Option A</div><p style="font-weight:600;margin-top:24px"><span data-cfm-question-number>2.</span> NPS question</p><div class="cfm-nps-track"><div class="cfm-nps-row">${npsCells}</div></div><div style="display:flex;gap:12px;margin-top:24px"><button data-cfm-btn-back class="cfm-btn-back">Back</button><button data-cfm-btn-next class="cfm-btn-primary">Next</button></div><footer class="cfm-footer" style="margin-top:32px"><p data-cfm-copyright>© Company</p><nav data-cfm-footer-links class="cfm-footer-links"></nav></footer>` },
|
|
95
|
+
{ key: 'MCQ_single', title: 'MCQ Single', body: `<p style="font-weight:600;margin-bottom:16px"><span data-cfm-question-number>1.</span> Select one option</p><div data-cfm-mcq-style="outlined"><div class="cfm-mcq-option selected"><span style="display:inline-flex;width:20px;height:20px;border-radius:50%;border:2px solid var(--cfm-input-focus-ring);align-items:center;justify-content:center"><span style="width:10px;height:10px;border-radius:50%;background:var(--cfm-input-focus-ring)"></span></span> Option A</div><div class="cfm-mcq-option"><span style="display:inline-flex;width:20px;height:20px;border-radius:50%;border:1px solid #9ca3af"></span> Option B</div><div class="cfm-mcq-option"><span style="display:inline-flex;width:20px;height:20px;border-radius:50%;border:1px solid #9ca3af"></span> Option C</div></div>` },
|
|
71
96
|
{ key: 'MCQ_multiple', title: 'MCQ Multiple', body: `<p style="font-weight:600;margin-bottom:16px">Select all that apply</p><div class="cfm-mcq-option selected"><span>☑</span> Option A</div><div class="cfm-mcq-option"><span>☐</span> Option B</div>` },
|
|
72
|
-
{ key: 'TEXTFIELD_short', title: 'Text Short', body: `<p style="font-weight:600;margin-bottom:8px">Your name</p><input class="cfm-input" placeholder="Type here..." />` },
|
|
73
|
-
{ key: 'TEXTFIELD_long', title: 'Text Long', body: `<p style="font-weight:600;margin-bottom:8px">Comments</p><textarea class="cfm-input" style="height:120px;padding:12px" placeholder="Type your response..."></textarea>` },
|
|
74
|
-
{ key: 'NPS_SCALE', title: 'NPS', body:
|
|
75
|
-
{ key: 'CFM_likert', title: 'CFM Likert', body: matrixPreview('Statement item 1') },
|
|
76
|
-
{ key: 'CFM_bipolar', title: 'CFM Bipolar', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label" style="width:var(--cfm-matrix-bipolar-width)">Left</div><div class="cfm-matrix-cells">${cells(5)}</div><div class="cfm-matrix-label" style="width:var(--cfm-matrix-bipolar-width);text-align:right">Right</div></div>` },
|
|
77
|
-
{ key: 'CFM_transpose', title: 'CFM Transpose', body: matrixPreview('Scale item (transposed)') },
|
|
78
|
-
{ key: 'CFM_carousel', title: 'CFM Carousel', body: `${matrixPreview('Row 1 of 3')}<div style="text-align:center;margin-top:12px"><span style="color:var(--cfm-matrix-
|
|
79
|
-
{ key: 'CFM_dropdown', title: 'CFM Dropdown', body: `<div class="cfm-matrix-label">Statement 1</div><select class="cfm-input"
|
|
80
|
-
{ key: 'CSAT_emoji', title: 'CSAT Emoji', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">How satisfied?</div><div class="cfm-matrix-cells"><span class="cfm-emoji selected">😞</span><span class="cfm-emoji">🙂</span><span class="cfm-emoji">😊</span></div></div>` },
|
|
81
|
-
{ key: 'CSAT_star', title: 'CSAT Star', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Rate us</div><div class="cfm-matrix-cells"><span class="cfm-star selected">★</span><span class="cfm-star selected">★</span><span class="cfm-star">★</span></div></div>` },
|
|
82
|
-
{ key: 'CSAT_numbered', title: 'CSAT Numbered', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Score</div><div class="cfm-matrix-cells"
|
|
97
|
+
{ key: 'TEXTFIELD_short', title: 'Text Short', body: `<p style="font-weight:600;margin-bottom:8px">Your name</p><input class="cfm-input" data-cfm-textfield placeholder="Type here..." />` },
|
|
98
|
+
{ key: 'TEXTFIELD_long', title: 'Text Long', body: `<p style="font-weight:600;margin-bottom:8px">Comments</p><textarea class="cfm-input" data-cfm-textfield style="height:120px;padding:12px" placeholder="Type your response..."></textarea>` },
|
|
99
|
+
{ key: 'NPS_SCALE', title: 'NPS', body: npsPreview() },
|
|
100
|
+
{ key: 'CFM_likert', title: 'CFM Likert', body: `${matrixPreview('Statement item 1', 'radio')}<div class="cfm-matrix-row" data-cfm-matrix-row-extra style="display:none"><div class="cfm-matrix-label">Statement item 2</div><div class="cfm-matrix-cells">${cells(5)}</div></div>` },
|
|
101
|
+
{ key: 'CFM_bipolar', title: 'CFM Bipolar', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label" style="width:var(--cfm-matrix-bipolar-width,25%)">Left statement</div><div class="cfm-matrix-cells">${cells(5)}</div><div class="cfm-matrix-label" style="width:var(--cfm-matrix-bipolar-width,25%);text-align:right">Right statement</div></div>` },
|
|
102
|
+
{ key: 'CFM_transpose', title: 'CFM Transpose', body: matrixPreview('Scale item (transposed row)', 'radio') },
|
|
103
|
+
{ key: 'CFM_carousel', title: 'CFM Carousel', body: `${matrixPreview('Row 1 of 3', 'radio')}<div style="text-align:center;margin-top:12px"><span style="color:var(--cfm-matrix-selected)">●</span> ○ ○</div>` },
|
|
104
|
+
{ key: 'CFM_dropdown', title: 'CFM Dropdown', body: `<div class="cfm-matrix-label" style="width:100%;margin-bottom:8px">Statement 1</div><select class="cfm-input"><option>Select...</option><option>Col 1</option><option>Col 2</option></select>` },
|
|
105
|
+
{ key: 'CSAT_emoji', title: 'CSAT Emoji', body: `<div class="cfm-matrix-row" style="background:transparent;margin-bottom:4px"><div class="cfm-matrix-label"></div><div class="cfm-matrix-cells">${colLabels(5)}</div></div><div class="cfm-matrix-row"><div class="cfm-matrix-label">How satisfied?</div><div class="cfm-matrix-cells"><span class="cfm-emoji selected">😞</span><span class="cfm-emoji">😐</span><span class="cfm-emoji">🙂</span><span class="cfm-emoji">😊</span><span class="cfm-emoji">🤩</span></div></div>` },
|
|
106
|
+
{ key: 'CSAT_star', title: 'CSAT Star', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Rate us</div><div class="cfm-matrix-cells"><span class="cfm-star selected">★</span><span class="cfm-star selected">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span></div></div>` },
|
|
107
|
+
{ key: 'CSAT_numbered', title: 'CSAT Numbered', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Score</div><div class="cfm-matrix-cells">${[1,2,3,4,5].map((n,i)=>`<div class="cfm-badge${i===2?' selected':''}" data-cfm-number-badge="${i}">${n}</div>`).join('')}</div></div>` },
|
|
83
108
|
{ key: 'CSAT_graphics', title: 'CSAT Graphics', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Slider row</div><div style="flex:1;padding:0 16px"><div class="cfm-slider-track"><div class="cfm-slider-thumb"></div></div></div></div>` },
|
|
84
|
-
{ key: 'CSAT_carousel', title: 'CSAT Carousel', body: `${matrixPreview('Carousel row')}<div style="text-align:center"><span style="color:var(--cfm-
|
|
109
|
+
{ key: 'CSAT_carousel', title: 'CSAT Carousel', body: `${matrixPreview('Carousel row', 'emoji')}<div style="text-align:center"><span style="color:var(--cfm-matrix-selected)">●</span> ○</div>` },
|
|
85
110
|
{ key: 'CSAT_dropdown', title: 'CSAT Dropdown', body: `<div class="cfm-matrix-label">Statement</div><select class="cfm-input" style="margin-top:8px"><option>Choose rating...</option></select>` },
|
|
86
|
-
{ key: 'RATING_star', title: 'Rating Star', body: `<div class="cfm-matrix-
|
|
87
|
-
{ key: 'RATING_numbered', title: 'Rating Numbered', body: `<div class="cfm-matrix-cells" style="padding:16px"
|
|
88
|
-
{ key: 'RATING_radio', title: 'Rating Radio', body: matrixPreview('Recommend to a friend') },
|
|
111
|
+
{ key: 'RATING_star', title: 'Rating Star', body: `<div class="cfm-matrix-row" style="background:transparent;margin-bottom:4px"><div class="cfm-matrix-label"></div><div class="cfm-matrix-cells">${['Strongly Disagree','Disagree','Neutral','Agree','Strongly Agree'].map(l=>`<span class="cfm-matrix-col-label">${l}</span>`).join('')}</div></div><div class="cfm-matrix-row"><div class="cfm-matrix-label">Statement Item 1</div><div class="cfm-matrix-cells"><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span></div></div><div class="cfm-matrix-row" data-cfm-matrix-row-extra style="display:none"><div class="cfm-matrix-label">Statement Item 2</div><div class="cfm-matrix-cells"><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span><span class="cfm-star">★</span></div></div>` },
|
|
112
|
+
{ key: 'RATING_numbered', title: 'Rating Numbered', body: `<div class="cfm-matrix-cells" style="padding:16px">${[1,2,3,4,5].map((n,i)=>`<div class="cfm-badge${i===1?' selected':''}" data-cfm-number-badge="${i}">${n}</div>`).join('')}</div>` },
|
|
113
|
+
{ key: 'RATING_radio', title: 'Rating Radio', body: matrixPreview('Recommend to a friend', 'radio') },
|
|
89
114
|
{ key: 'RATING_emoji', title: 'Rating Emoji', body: `<div class="cfm-matrix-cells" style="padding:16px"><span class="cfm-emoji">🙂</span><span class="cfm-emoji selected">😊</span><span class="cfm-emoji">🤩</span></div>` },
|
|
90
115
|
{ key: 'RATING_graphics', title: 'Rating Graphics', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Experience</div><div style="flex:1;padding:0 16px"><div class="cfm-slider-track"><div class="cfm-slider-thumb"></div></div></div></div>` },
|
|
91
116
|
{ key: 'RATING_slider', title: 'Rating Slider', body: `<div class="cfm-matrix-row"><div class="cfm-matrix-label">Rate on slider</div><div style="flex:1;padding:0 16px"><div class="cfm-slider-track"><div class="cfm-slider-thumb"></div></div></div></div>` },
|
|
92
|
-
{ key: 'SLIDER_matrix', title: 'Slider Matrix', body: `<div
|
|
93
|
-
{ key: 'FILE_UPLOAD', title: 'File Upload', body: `<div
|
|
94
|
-
{ key: 'TEXT_AND_MEDIA', title: 'Text & Media', body: `<div class="cfm-media">Media preview</div>` },
|
|
95
|
-
{ key: 'HEATMAP', title: 'Heatmap', body: `<div style="position:relative;background:#e5e7eb;height:240px;border-radius:var(--cfm-border-radius)"><div class="cfm-pin" style="top:40%;left:55%"></div></div>` },
|
|
117
|
+
{ key: 'SLIDER_matrix', title: 'Slider Matrix', body: `<div style="display:flex;gap:4px;margin-bottom:16px;padding-left:var(--cfm-matrix-row-width,180px)">${Array.from({length:11},(_,i)=>`<div class="cfm-tick" data-cfm-number-badge="${i}" style="background:${TRAFFIC[i]??'#6b7280'}">${i}</div>`).join('')}</div><div style="display:flex;gap:8px;margin-bottom:8px;padding-left:var(--cfm-matrix-row-width,180px)"><span class="cfm-slider-tick-label">Label 1</span><span class="cfm-slider-tick-label" style="margin-left:auto">Label 2</span></div><div class="cfm-matrix-row" style="background:var(--cfm-slider-row-band,#f3f4f6);border-radius:8px;padding:12px 0"><div class="cfm-matrix-label">Statement Item 1</div><div style="flex:1;padding:0 16px"><div class="cfm-slider-track"><div class="cfm-slider-thumb" style="left:50%"></div></div></div></div><div class="cfm-matrix-row" data-cfm-matrix-row-extra style="display:none;background:var(--cfm-slider-row-band,#f3f4f6);border-radius:8px;padding:12px 0"><div class="cfm-matrix-label">Statement Item 2</div><div style="flex:1;padding:0 16px"><div class="cfm-slider-track"><div class="cfm-slider-thumb" style="left:0%"></div></div></div></div>` },
|
|
118
|
+
{ key: 'FILE_UPLOAD', title: 'File Upload', body: `<div class="cfm-dropzone" data-cfm-dropzone>Drop files here or click to upload</div>` },
|
|
119
|
+
{ key: 'TEXT_AND_MEDIA', title: 'Text & Media', body: `<div class="cfm-media">Media preview</div><p style="font-size:var(--cfm-media-caption-size,12px);color:var(--cfm-media-caption-color,#6b7280);margin-top:8px">Caption text</p>` },
|
|
120
|
+
{ key: 'HEATMAP', title: 'Heatmap', body: `<div style="position:relative;background:#e5e7eb;height:240px;border-radius:var(--cfm-border-radius)"><div class="cfm-pin" style="top:40%;left:55%"></div><div class="cfm-pin" style="top:60%;left:30%"></div></div>` },
|
|
96
121
|
{ key: 'RANK_drag', title: 'Rank Drag', body: `<div class="cfm-rank-item"><span class="cfm-handle">⠿</span><span class="cfm-rank-badge">1</span> Item A</div><div class="cfm-rank-item"><span class="cfm-handle">⠿</span><span class="cfm-rank-badge">2</span> Item B</div>` },
|
|
97
|
-
{ key: 'RANK_dropdown', title: 'Rank Dropdown', body: `<div
|
|
122
|
+
{ key: 'RANK_dropdown', title: 'Rank Dropdown', body: `<div class="cfm-rank-item"><span>Item A</span><select class="cfm-input cfm-rank-select" style="width:80px;margin-left:auto"><option>1</option><option>2</option></select></div>` },
|
|
98
123
|
];
|
|
99
124
|
|
|
100
125
|
function buildPreviewHtml(def, inlineCss, inlineJs) {
|
|
@@ -113,4 +138,4 @@ function buildPreviewHtml(def, inlineCss, inlineJs) {
|
|
|
113
138
|
</html>`;
|
|
114
139
|
}
|
|
115
140
|
|
|
116
|
-
module.exports = { PREVIEW_PAGE_DEFS, buildPreviewHtml, sharedStyles, PREVIEW_KEYS: PREVIEW_PAGE_DEFS.map((d) => d.key) };
|
|
141
|
+
module.exports = { PREVIEW_PAGE_DEFS, buildPreviewHtml, sharedStyles, PREVIEW_KEYS: PREVIEW_PAGE_DEFS.map((d) => d.key), TRAFFIC };
|
|
@@ -11,17 +11,17 @@ const sharedStyles = `
|
|
|
11
11
|
.cfm-progress { height:var(--cfm-progress-height); background:var(--cfm-progress-track); border-radius:999px; overflow:hidden; margin:var(--cfm-sticky-pt) 0 var(--cfm-sticky-pb); }
|
|
12
12
|
.cfm-progress-fill { height:100%; width:45%; background:var(--cfm-progress-fill); border-radius:999px; }
|
|
13
13
|
.cfm-mcq-option { border:2px solid #e5e7eb; border-radius:var(--cfm-mcq-border-radius); padding:var(--cfm-mcq-card-padding); margin-bottom:var(--cfm-mcq-option-gap); display:flex; align-items:center; gap:8px; }
|
|
14
|
-
.cfm-mcq-option.selected { border-color:var(--cfm-
|
|
14
|
+
.cfm-mcq-option.selected { border-color:var(--cfm-input-focus-ring); background:var(--cfm-mcq-selected-bg); }
|
|
15
15
|
.cfm-nps-row { display:flex; gap:var(--cfm-nps-cell-gap); flex-wrap:wrap; }
|
|
16
|
-
.cfm-nps-cell { width:var(--cfm-nps-cell-size); height:var(--cfm-nps-cell-size); border-radius:var(--cfm-border-radius); background:var(--cfm-nps-track-bar); display:flex; align-items:center; justify-content:center; font-size:14px; }
|
|
17
|
-
.cfm-nps-cell.selected {
|
|
16
|
+
.cfm-nps-cell { width:var(--cfm-nps-cell-size); height:var(--cfm-nps-cell-size); border-radius:var(--cfm-border-radius); background:var(--cfm-nps-track-bar); display:flex; align-items:center; justify-content:center; font-size:14px; border:2px solid transparent; box-sizing:border-box; }
|
|
17
|
+
.cfm-nps-cell.selected { border-color:var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); }
|
|
18
18
|
.cfm-matrix-row { display:flex; align-items:center; padding:8px 0; background:var(--cfm-row-band); margin-bottom:4px; }
|
|
19
19
|
.cfm-matrix-label { width:var(--cfm-matrix-row-width); flex-shrink:0; padding:0 16px; font-size:14px; font-weight:500; }
|
|
20
20
|
.cfm-matrix-cells { display:flex; gap:8px; flex:1; justify-content:center; }
|
|
21
|
-
.cfm-matrix-cell { width:var(--cfm-csat-cell-size); height:var(--cfm-csat-cell-size); border-radius:50%; border:2px solid #d1d5db; }
|
|
22
|
-
.cfm-matrix-cell.selected { border-color:var(--cfm-
|
|
21
|
+
.cfm-matrix-cell { width:var(--cfm-csat-cell-size); height:var(--cfm-csat-cell-size); border-radius:50%; border:2px solid #d1d5db; box-sizing:border-box; }
|
|
22
|
+
.cfm-matrix-cell.selected { border-color:var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); }
|
|
23
23
|
.cfm-emoji { font-size:var(--cfm-csat-emoji-size); opacity:var(--cfm-csat-unselected-opacity); }
|
|
24
|
-
.cfm-emoji.selected { opacity:1; outline:2px solid var(--cfm-
|
|
24
|
+
.cfm-emoji.selected { opacity:1; outline:2px solid var(--cfm-input-focus-ring); background:var(--cfm-matrix-selected); border-radius:50%; }
|
|
25
25
|
.cfm-star { color:var(--cfm-star-color); font-size:24px; opacity:var(--cfm-star-unselected-opacity); }
|
|
26
26
|
.cfm-star.selected { opacity:1; }
|
|
27
27
|
.cfm-badge { width:40px; height:40px; border-radius:8px; background:var(--cfm-badge-color); color:white; display:flex; align-items:center; justify-content:center; font-weight:600; }
|
|
@@ -75,20 +75,6 @@ export const PREVIEW_PAGE_DEFS: PreviewPageDef[] = [
|
|
|
75
75
|
<nav data-cfm-footer-links class="cfm-footer-links"></nav>
|
|
76
76
|
</footer>`,
|
|
77
77
|
},
|
|
78
|
-
{
|
|
79
|
-
key: 'chrome',
|
|
80
|
-
title: 'Chrome',
|
|
81
|
-
body: `<header class="cfm-header">
|
|
82
|
-
<img data-cfm-logo class="cfm-header-logo" src="" alt="" style="display:none" />
|
|
83
|
-
<span data-cfm-company class="cfm-header-company">Company</span>
|
|
84
|
-
</header>
|
|
85
|
-
<div class="cfm-progress"><div class="cfm-progress-fill"></div></div>
|
|
86
|
-
<p data-cfm-survey-title style="font-size:20px;font-weight:var(--cfm-heading-weight);margin:16px 0">Survey Title</p>
|
|
87
|
-
<div style="display:flex;gap:12px;margin-top:24px">
|
|
88
|
-
<button data-cfm-btn-back class="cfm-btn-back">Back</button>
|
|
89
|
-
<button data-cfm-btn-next class="cfm-btn-primary">Next</button>
|
|
90
|
-
</div>`,
|
|
91
|
-
},
|
|
92
78
|
{
|
|
93
79
|
key: 'survey_page',
|
|
94
80
|
title: 'Survey Page',
|
|
@@ -101,7 +87,7 @@ export const PREVIEW_PAGE_DEFS: PreviewPageDef[] = [
|
|
|
101
87
|
<p style="font-weight:600"><span data-cfm-question-number>1.</span> Sample question <span data-cfm-required style="color:red">*</span></p>
|
|
102
88
|
<div class="cfm-mcq-option selected"><span>◉</span> Option A</div>
|
|
103
89
|
<p style="font-weight:600;margin-top:24px"><span data-cfm-question-number>2.</span> NPS question</p>
|
|
104
|
-
<div class="cfm-nps-row">${Array.from({ length: 11 }, (_, i) => `<div class="cfm-nps-cell">${i}</div>`).join('')}</div>
|
|
90
|
+
<div class="cfm-nps-row">${Array.from({ length: 11 }, (_, i) => `<div class="cfm-nps-cell${i === 8 ? ' selected' : ''}">${i}</div>`).join('')}</div>
|
|
105
91
|
<div style="display:flex;gap:12px;margin-top:24px">
|
|
106
92
|
<button data-cfm-btn-back class="cfm-btn-back">Back</button>
|
|
107
93
|
<button data-cfm-btn-next class="cfm-btn-primary">Next</button>
|
|
@@ -111,19 +97,6 @@ export const PREVIEW_PAGE_DEFS: PreviewPageDef[] = [
|
|
|
111
97
|
<nav data-cfm-footer-links class="cfm-footer-links"></nav>
|
|
112
98
|
</footer>`,
|
|
113
99
|
},
|
|
114
|
-
{
|
|
115
|
-
key: 'intro',
|
|
116
|
-
title: 'Intro',
|
|
117
|
-
body: `<h1 data-cfm-survey-title style="font-size:28px;font-weight:var(--cfm-heading-weight)">Welcome</h1>
|
|
118
|
-
<p style="margin:16px 0;color:#6b7280">Please take a few minutes to share your feedback.</p>
|
|
119
|
-
<button class="cfm-btn-primary">Start Survey</button>`,
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
key: 'end',
|
|
123
|
-
title: 'End',
|
|
124
|
-
body: `<h1 style="font-size:28px;font-weight:var(--cfm-heading-weight)">Thank you!</h1>
|
|
125
|
-
<p data-cfm-thank-you style="margin:16px 0">Thank you for your feedback.</p>`,
|
|
126
|
-
},
|
|
127
100
|
{
|
|
128
101
|
key: 'MCQ_single',
|
|
129
102
|
title: 'MCQ Single',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
export type PreviewStatePatch = {
|
|
4
|
+
activePreviewKey?: string;
|
|
4
5
|
multiStatement?: boolean;
|
|
5
6
|
textfieldPlaceholder?: string;
|
|
6
7
|
npsButtonStyle?: string;
|
|
@@ -40,6 +41,12 @@ export function PreviewConfigProvider({ children }: { children: ReactNode }) {
|
|
|
40
41
|
root.setAttribute(key, value as string);
|
|
41
42
|
}
|
|
42
43
|
}
|
|
44
|
+
if (data.cssVars) {
|
|
45
|
+
const root = document.documentElement;
|
|
46
|
+
for (const [key, value] of Object.entries(data.cssVars)) {
|
|
47
|
+
root.style.setProperty(key, value as string);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
43
50
|
};
|
|
44
51
|
|
|
45
52
|
window.addEventListener('message', handler);
|
|
@@ -27,12 +27,33 @@ function resolveNumberLabelColor(index: number): string {
|
|
|
27
27
|
return '';
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function applyMatrixRowCount<T extends SurveyQuestion & { statementRows?: { id: string; statementText: string }[] }>(
|
|
31
|
+
q: T,
|
|
32
|
+
multiStatement: boolean | undefined,
|
|
33
|
+
): T {
|
|
34
|
+
if (!('statementRows' in q) || !Array.isArray(q.statementRows)) return q;
|
|
35
|
+
const rows = q.statementRows;
|
|
36
|
+
if (multiStatement) {
|
|
37
|
+
if (rows.length >= 2) return q;
|
|
38
|
+
return {
|
|
39
|
+
...q,
|
|
40
|
+
statementRows: [
|
|
41
|
+
...rows,
|
|
42
|
+
{ id: 'r2', statementText: 'Statement Item 2' },
|
|
43
|
+
...(rows.length === 1 ? [{ id: 'r3', statementText: 'Statement Item 3' }] : []),
|
|
44
|
+
],
|
|
45
|
+
} as T;
|
|
46
|
+
}
|
|
47
|
+
return { ...q, statementRows: rows.slice(0, 1) } as T;
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
function QuestionPreviewInner({ question, initialValue }: QuestionPreviewProps) {
|
|
31
51
|
const { previewState } = usePreviewConfig();
|
|
32
52
|
const [value, setValue] = useState<AnswerValue | undefined>(initialValue);
|
|
33
53
|
|
|
34
54
|
const mergedQuestion = useMemo(() => {
|
|
35
55
|
let q = { ...question } as SurveyQuestion;
|
|
56
|
+
const previewKey = previewState.activePreviewKey ?? '';
|
|
36
57
|
|
|
37
58
|
if (previewState.textfieldPlaceholder && q.type === 'TEXTFIELD') {
|
|
38
59
|
q = { ...q, placeholder: previewState.textfieldPlaceholder };
|
|
@@ -40,31 +61,15 @@ function QuestionPreviewInner({ question, initialValue }: QuestionPreviewProps)
|
|
|
40
61
|
|
|
41
62
|
if (previewState.npsButtonStyle && q.type === 'NPS_SCALE') {
|
|
42
63
|
const style = previewState.npsButtonStyle;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
q = {
|
|
53
|
-
...q,
|
|
54
|
-
statementRows:
|
|
55
|
-
rows.length >= 2
|
|
56
|
-
? rows
|
|
57
|
-
: [
|
|
58
|
-
...rows,
|
|
59
|
-
{
|
|
60
|
-
id: 'r2',
|
|
61
|
-
statementText: 'Second statement row',
|
|
62
|
-
},
|
|
63
|
-
],
|
|
64
|
-
} as typeof q;
|
|
65
|
-
} else {
|
|
66
|
-
q = { ...q, statementRows: rows.slice(0, 1) } as typeof q;
|
|
67
|
-
}
|
|
64
|
+
const buttonStyle =
|
|
65
|
+
style === 'numbered'
|
|
66
|
+
? 'numbered'
|
|
67
|
+
: style === 'pill'
|
|
68
|
+
? 'pill'
|
|
69
|
+
: style === 'emoji'
|
|
70
|
+
? 'emoji'
|
|
71
|
+
: 'standard';
|
|
72
|
+
q = { ...q, buttonStyle };
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
if (previewState.hintMinText !== undefined || previewState.hintMaxText !== undefined) {
|
|
@@ -86,13 +91,37 @@ function QuestionPreviewInner({ question, initialValue }: QuestionPreviewProps)
|
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
|
|
89
|
-
if (
|
|
90
|
-
|
|
94
|
+
if (q.type === 'CFM_MATRIX') {
|
|
95
|
+
if (previewKey === 'CFM_bipolar') {
|
|
96
|
+
q = {
|
|
97
|
+
...q,
|
|
98
|
+
statementLayout: 'bipolar',
|
|
99
|
+
showColumnHeaders: false,
|
|
100
|
+
gridLayout: 'standard',
|
|
101
|
+
transposeTable: false,
|
|
102
|
+
};
|
|
103
|
+
} else if (previewKey === 'CFM_transpose') {
|
|
104
|
+
q = { ...q, statementLayout: 'likert', transposeTable: true, gridLayout: 'standard' };
|
|
105
|
+
} else if (previewKey === 'CFM_carousel') {
|
|
106
|
+
q = { ...q, statementLayout: 'likert', gridLayout: 'carousel', transposeTable: false };
|
|
107
|
+
} else if (previewKey === 'CFM_dropdown') {
|
|
108
|
+
q = { ...q, statementLayout: 'likert', gridLayout: 'dropdown', transposeTable: false };
|
|
109
|
+
} else {
|
|
110
|
+
q = { ...q, statementLayout: 'likert', gridLayout: 'standard', transposeTable: false };
|
|
111
|
+
}
|
|
91
112
|
}
|
|
92
|
-
|
|
93
|
-
|
|
113
|
+
|
|
114
|
+
if (q.type === 'RANK_ORDER') {
|
|
115
|
+
if (previewState.rankVariant === 'drag' || previewKey === 'RANK_drag') {
|
|
116
|
+
q = { ...q, interactionMode: 'dragAndDrop', optionDisplay: 'textAndImage' };
|
|
117
|
+
}
|
|
118
|
+
if (previewState.rankVariant === 'dropdown' || previewKey === 'RANK_dropdown') {
|
|
119
|
+
q = { ...q, interactionMode: 'dropdown', optionDisplay: 'textAndImage' };
|
|
120
|
+
}
|
|
94
121
|
}
|
|
95
122
|
|
|
123
|
+
q = applyMatrixRowCount(q, previewState.multiStatement);
|
|
124
|
+
|
|
96
125
|
return q;
|
|
97
126
|
}, [question, previewState]);
|
|
98
127
|
|
|
@@ -109,7 +138,7 @@ function QuestionPreviewInner({ question, initialValue }: QuestionPreviewProps)
|
|
|
109
138
|
|
|
110
139
|
return (
|
|
111
140
|
<div
|
|
112
|
-
className="
|
|
141
|
+
className="mx-auto max-w-4xl px-4 py-6"
|
|
113
142
|
style={{ fontFamily: 'var(--cfm-font-family)' }}
|
|
114
143
|
data-cfm-question-area
|
|
115
144
|
>
|
|
@@ -4,11 +4,23 @@ import SurveyStickyChrome from '@/components/SurveyStickyChrome';
|
|
|
4
4
|
import LanguageSelector from '@/components/LanguageSelector';
|
|
5
5
|
import Question from '@/components/Question';
|
|
6
6
|
import Footer from '@/components/Footer';
|
|
7
|
-
import {
|
|
7
|
+
import { PreviewConfigProvider } from './PreviewConfigContext';
|
|
8
|
+
import {
|
|
9
|
+
FIXTURE_SURVEY_PAGE_MCQ,
|
|
10
|
+
FIXTURE_SURVEY_PAGE_NPS,
|
|
11
|
+
PREVIEW_LANGUAGES,
|
|
12
|
+
} from './fixtures/questions';
|
|
8
13
|
|
|
9
|
-
|
|
14
|
+
function SurveyPagePreviewInner() {
|
|
10
15
|
const [lang, setLang] = useState('en');
|
|
11
|
-
const [
|
|
16
|
+
const [mcqAnswer, setMcqAnswer] = useState<AnswerValue>('a');
|
|
17
|
+
const [npsAnswer, setNpsAnswer] = useState<AnswerValue>(8);
|
|
18
|
+
|
|
19
|
+
const allQuestions = [FIXTURE_SURVEY_PAGE_MCQ, FIXTURE_SURVEY_PAGE_NPS];
|
|
20
|
+
const allAnswers = {
|
|
21
|
+
[FIXTURE_SURVEY_PAGE_MCQ.id]: mcqAnswer,
|
|
22
|
+
[FIXTURE_SURVEY_PAGE_NPS.id]: npsAnswer,
|
|
23
|
+
};
|
|
12
24
|
|
|
13
25
|
return (
|
|
14
26
|
<div
|
|
@@ -30,13 +42,20 @@ export function SurveyPagePreview() {
|
|
|
30
42
|
onChange={setLang}
|
|
31
43
|
/>
|
|
32
44
|
|
|
33
|
-
<div className="space-y-
|
|
45
|
+
<div className="space-y-8">
|
|
46
|
+
<Question
|
|
47
|
+
question={FIXTURE_SURVEY_PAGE_MCQ}
|
|
48
|
+
selectedValue={mcqAnswer}
|
|
49
|
+
allAnswers={allAnswers}
|
|
50
|
+
allQuestions={allQuestions}
|
|
51
|
+
onSelect={setMcqAnswer}
|
|
52
|
+
/>
|
|
34
53
|
<Question
|
|
35
54
|
question={FIXTURE_SURVEY_PAGE_NPS}
|
|
36
|
-
selectedValue={
|
|
37
|
-
allAnswers={
|
|
38
|
-
allQuestions={
|
|
39
|
-
onSelect={
|
|
55
|
+
selectedValue={npsAnswer}
|
|
56
|
+
allAnswers={allAnswers}
|
|
57
|
+
allQuestions={allQuestions}
|
|
58
|
+
onSelect={setNpsAnswer}
|
|
40
59
|
/>
|
|
41
60
|
</div>
|
|
42
61
|
|
|
@@ -73,3 +92,12 @@ export function SurveyPagePreview() {
|
|
|
73
92
|
</div>
|
|
74
93
|
);
|
|
75
94
|
}
|
|
95
|
+
|
|
96
|
+
/** Full survey page mockup for wizard Theme / Layout steps — header, progress, language, cards, footer. */
|
|
97
|
+
export function SurveyPagePreview() {
|
|
98
|
+
return (
|
|
99
|
+
<PreviewConfigProvider>
|
|
100
|
+
<SurveyPagePreviewInner />
|
|
101
|
+
</PreviewConfigProvider>
|
|
102
|
+
);
|
|
103
|
+
}
|