@explorer02/cfm-survey-sdk 0.2.1 → 0.2.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.
Files changed (88) hide show
  1. package/dist/cli/index.js +18 -18
  2. package/dist/cli/index.mjs +14 -14
  3. package/dist/index.d.mts +465 -580
  4. package/dist/index.d.ts +465 -580
  5. package/dist/index.js +1 -1
  6. package/dist/index.mjs +1 -1
  7. package/package.json +6 -4
  8. package/postinstall.js +96 -69
  9. package/templates/AGENT.md +14 -8
  10. package/templates/docs/00-integration/answer-logic-and-navigation.md +50 -0
  11. package/templates/docs/00-integration/aws-deploy.md +281 -0
  12. package/templates/docs/00-integration/client-integration-guide.md +351 -0
  13. package/templates/docs/00-integration/component-checklist.md +45 -22
  14. package/templates/docs/00-integration/constraints.md +49 -4
  15. package/templates/docs/00-integration/custom-field-logic-and-navigation.md +174 -0
  16. package/templates/docs/00-integration/display-logic-and-navigation.md +49 -0
  17. package/templates/docs/00-integration/end-page-logic.md +64 -0
  18. package/templates/docs/00-integration/partial-save-and-recovery.md +74 -0
  19. package/templates/docs/00-integration/placeholders-and-tokens.md +116 -0
  20. package/templates/docs/00-integration/progress.md +61 -0
  21. package/templates/docs/00-integration/question-display-variants.md +65 -0
  22. package/templates/docs/00-integration/question-numbering.md +51 -0
  23. package/templates/docs/00-integration/question-type-sdk-matrix.md +242 -0
  24. package/templates/docs/00-integration/setup.md +84 -0
  25. package/templates/docs/00-integration/skip-logic-and-navigation.md +80 -0
  26. package/templates/docs/00-integration/survey-lifecycle-analytics.md +94 -0
  27. package/templates/docs/00-integration/useSurveySDK.md +151 -23
  28. package/templates/docs/01-components/01-survey-page.md +76 -54
  29. package/templates/docs/01-components/02-question.md +61 -58
  30. package/templates/docs/01-components/03-rating-scale.md +11 -1
  31. package/templates/docs/01-components/04-star-rating-scale.md +45 -0
  32. package/templates/docs/01-components/05-csat-matrix-scale.md +20 -11
  33. package/templates/docs/01-components/06-likert-matrix-scale.md +12 -3
  34. package/templates/docs/01-components/07-slider-matrix-scale.md +11 -2
  35. package/templates/docs/01-components/08-file-upload-scale.md +10 -1
  36. package/templates/docs/01-components/09-custom-slider-track.md +2 -2
  37. package/templates/docs/01-components/11-progress-bar.md +10 -4
  38. package/templates/docs/01-components/13-matrix-dropdown.md +3 -1
  39. package/templates/docs/01-components/14-intro-page.md +34 -0
  40. package/templates/docs/01-components/15-end-page.md +31 -0
  41. package/templates/docs/01-components/16-paused-page.md +27 -0
  42. package/templates/docs/01-components/17-heatmap-scale.md +75 -0
  43. package/templates/docs/01-components/18-rank-order-scale.md +100 -0
  44. package/templates/docs/01-components/README.md +42 -36
  45. package/templates/docs/02-reference/config-field-index.md +141 -139
  46. package/templates/docs/02-reference/exports.md +149 -0
  47. package/templates/docs/02-reference/question-types/01-rating.md +31 -32
  48. package/templates/docs/02-reference/question-types/04-csat.md +51 -42
  49. package/templates/docs/02-reference/question-types/05-rating-scale.md +16 -11
  50. package/templates/docs/02-reference/question-types/06-slider.md +2 -2
  51. package/templates/docs/02-reference/question-types/07-matrix-cfm.md +44 -30
  52. package/templates/docs/02-reference/question-types/08-matrix-csat.md +4 -26
  53. package/templates/docs/02-reference/question-types/09-matrix-rating.md +29 -13
  54. package/templates/docs/02-reference/question-types/10-slider-matrix.md +15 -4
  55. package/templates/docs/02-reference/question-types/11-file-upload.md +13 -2
  56. package/templates/docs/02-reference/question-types/12-heatmap.md +59 -0
  57. package/templates/docs/02-reference/question-types/13-rank-order.md +101 -0
  58. package/templates/docs/02-reference/question-types/README.md +86 -47
  59. package/templates/docs/02-reference/routing-table.md +33 -18
  60. package/templates/docs/02-reference/value-derivation.md +63 -0
  61. package/templates/docs/03-ui-specs/00-question-shell.md +19 -88
  62. package/templates/docs/03-ui-specs/01-rating.md +12 -54
  63. package/templates/docs/03-ui-specs/02-radio.md +21 -33
  64. package/templates/docs/03-ui-specs/03-text.md +2 -2
  65. package/templates/docs/03-ui-specs/04-csat.md +38 -33
  66. package/templates/docs/03-ui-specs/05-rating-scale.md +21 -18
  67. package/templates/docs/03-ui-specs/06-slider.md +3 -1
  68. package/templates/docs/03-ui-specs/07-matrix-cfm.md +24 -21
  69. package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +17 -45
  70. package/templates/docs/03-ui-specs/09-slider-matrix.md +1 -1
  71. package/templates/docs/03-ui-specs/10-file-upload.md +1 -1
  72. package/templates/docs/03-ui-specs/11-text-and-media.md +29 -29
  73. package/templates/docs/03-ui-specs/12-survey-chrome.md +20 -14
  74. package/templates/docs/03-ui-specs/13-heatmap.md +73 -0
  75. package/templates/docs/03-ui-specs/14-rank-order.md +59 -0
  76. package/templates/docs/03-ui-specs/README.md +13 -13
  77. package/templates/docs/03-ui-specs/shared/custom-slider-track.md +2 -2
  78. package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +5 -0
  79. package/templates/docs/MANIFEST.json +451 -69
  80. package/templates/docs/index.md +80 -29
  81. package/templates/docs/templates/Question.tsx +221 -154
  82. package/templates/docs/templates/deploy-to-aws.sh +114 -0
  83. package/templates/docs/templates/heatmapCoords.ts +58 -0
  84. package/templates/docs/templates/implementation_plan.md +108 -69
  85. package/templates/docs/templates/survey-inventory.schema.json +72 -0
  86. package/templates/docs/templates/verify-agent-build.sh +53 -0
  87. package/templates/docs/01-components/04-csat-scale.md +0 -40
  88. package/templates/docs/02-question-types/01-rating.md +0 -44
@@ -1,158 +1,160 @@
1
1
  # Config Field Index
2
2
 
3
- > Master map: every SDK config field → reference client file → implemented? → UI spec doc.
3
+ > Master map: every SDK config field → UI spec doc.
4
4
  > Cross-check this when building any question with non-default config.
5
5
 
6
- ## QuestionBase (all types)
7
-
8
- | Field | Types | Client file | Implemented? | Spec doc |
9
- |-------|-------|-------------|--------------|----------|
10
- | `id` | all | Question.tsx | ✅ | 00-question-shell |
11
- | `text` | all | Question.tsx | ✅ | 00-question-shell |
12
- | `description` | all | Question.tsx | ✅ | 00-question-shell |
13
- | `required` | all | Question.tsx | ✅ | 00-question-shell |
14
- | `requiredErrorMessage` | all | Question.tsx | ✅ | 00-question-shell |
15
- | `questionNumber` | all | — | ❌ | 00-question-shell |
16
- | `containerMediaUrl` | all | — | ❌ | 00-question-shell |
17
- | `containerMediaMimeType` | all | — | ❌ | 00-question-shell |
18
- | `containerMediaAlignment` | all | — | ❌ | 00-question-shell |
19
- | `containerMediaSize` | all | — | ❌ | 00-question-shell |
20
-
21
- ## rating
22
-
23
- | Field | Values | Client file | Implemented? | Spec doc |
24
- |-------|--------|-------------|--------------|----------|
25
- | `options[]` | SurveyOption[] | RatingScale.tsx | | 01-rating |
26
- | `options[].color` | hex | RatingScale.tsx | ✅ | 01-rating |
27
- | `minLabel` | string | Question.tsx | ✅ | 01-rating |
28
- | `midLabel` | string | Question.tsx | | 01-rating |
29
- | `maxLabel` | string | Question.tsx | ✅ | 01-rating |
30
- | `midLabelIndex` | number | Question.tsx | ✅ | 01-rating |
31
- | `reverseScaleOrder` | boolean | — | ❌ | 01-rating |
32
- | `buttonVariant` | radio/numbered/emoji | — | ❌ | 01-rating |
33
-
34
- ## radio
35
-
36
- | Field | Values | Client file | Implemented? | Spec doc |
37
- |-------|--------|-------------|--------------|----------|
38
- | `options[]` | SurveyOption[] | Question.tsx | ✅ | 02-radio |
39
- | `isMultiSelect` | boolean | — | ❌ | 02-radio |
40
-
41
- ## text
42
-
43
- | Field | Values | Client file | Implemented? | Spec doc |
44
- |-------|--------|-------------|--------------|----------|
45
- | `placeholder` | string | Question.tsx | | 03-text |
46
- | `maxCharacterCount` | number | Question.tsx | ✅ | 03-text |
47
- | `inputVariant` | long/short | Question.tsx | partial | 03-text |
48
-
49
- ## csat
50
-
51
- | Field | Values | Client file | Implemented? | Spec doc |
52
- |-------|--------|-------------|--------------|----------|
53
- | `options[]` | SurveyOption[] | CsatScale.tsx | | 04-csat |
54
- | `buttonType` | emoji/star/numbered/... | CsatScale.tsx | ✅ | 04-csat |
55
- | `labelPosition` | top/bottom/hidden | CsatScale.tsx | ✅ | 04-csat |
56
- | `minLabel` / `maxLabel` | string | Question.tsx | ✅ | 04-csat |
57
- | `hasNotApplicable` | boolean | — | ❌ | 04-csat |
58
- | `reverseScaleOrder` | boolean | — | ❌ | 04-csat |
59
-
60
- ## rating_scale
61
-
62
- | Field | Values | Client file | Implemented? | Spec doc |
63
- |-------|--------|-------------|--------------|----------|
64
- | `options[]` | SurveyOption[] | — | ❌ | 05-rating-scale |
65
- | `scaleStyle` | star/emoji | | | 05-rating-scale |
66
- | `minLabel` / `midLabel` / `maxLabel` | string | — | ❌ | 05-rating-scale |
67
- | `midLabelIndex` | number | — | ❌ | 05-rating-scale |
68
- | `reverseScaleOrder` | boolean | — | ❌ | 05-rating-scale |
6
+ ## Question shell (all types)
7
+
8
+ | Field | Types | Spec doc |
9
+ |-------|-------|----------|
10
+ | `id` | all | 00-question-shell |
11
+ | `questionText` | all | 00-question-shell |
12
+ | `questionDescription` | all | 00-question-shell |
13
+ | `questionHint` | all | 00-question-shell |
14
+ | `required` | all | 00-question-shell |
15
+ | `requiredErrorMessage` | all | 00-question-shell |
16
+ | `questionNumber` | all | 00-question-shell |
17
+ | `containerMedia` | ContainerMedia? | 00-question-shell |
18
+ | `containerMedia.url` | string | 00-question-shell |
19
+ | `containerMedia.mimeType` | string | 00-question-shell |
20
+ | `containerMedia.alignment` | string | 00-question-shell |
21
+ | `containerMedia.size` | number | 00-question-shell |
22
+
23
+ ## nps
24
+
25
+ | Field | Values | Spec doc |
26
+ |-------|--------|----------|
27
+ | `options[]` | NpsScalePoint[] | 01-rating |
28
+ | `minLabel` / `midLabel` / `maxLabel` | string | 01-rating |
29
+ | `midLabelIndex` | number | 01-rating |
30
+ | `reverseScaleOrder` | boolean | 01-rating |
31
+ | `buttonStyle` | standard/numbered/emoji | 01-rating |
32
+
33
+ ## mcq
34
+
35
+ | Field | Values | Spec doc |
36
+ |-------|--------|----------|
37
+ | `options[]` | McqOption[] | 02-radio |
38
+ | `selectionMode` | single/multiple | 02-radio |
39
+ | `displayFormat` | list/grid | 02-radio |
40
+ | `shuffleOptions` | boolean | 02-radio |
41
+ | `columnCount` | number | 02-radio |
42
+
43
+ ## text_input
44
+
45
+ | Field | Values | Spec doc |
46
+ |-------|--------|----------|
47
+ | `placeholder` | string | 03-text |
48
+ | `maxCharacterCount` | number | 03-text |
49
+ | `inputVariant` | long/short | 03-text |
50
+
51
+ ## csat (matrix grid)
52
+
53
+ | Field | Values | Spec doc |
54
+ |-------|--------|----------|
55
+ | `statementRows[]` | CsatStatementRow[] | 04-csat |
56
+ | `scaleColumns[]` | CsatScaleColumn[] | 04-csat |
57
+ | `displayStyle` | emoji/star/standard/numbered/dropdown/selectbox/graphics | 04-csat |
58
+ | `gridLayout` | standard/carousel/dropdown | 04-csat |
59
+ | `hasNotApplicableOption` | boolean | 04-csat |
60
+ | `reverseScaleOrder` | boolean | 04-csat |
61
+ | `scaleAnchorLabels[]` | string[] | 04-csat |
62
+
63
+ ## star_rating
64
+
65
+ | Field | Values | Spec doc |
66
+ |-------|--------|----------|
67
+ | `options[]` | StarRatingPoint[] | 05-rating-scale |
68
+ | `scaleStyle` | star/emoji | 05-rating-scale |
69
+ | `minLabel` / `midLabel` / `maxLabel` | string | 05-rating-scale |
70
+ | `midLabelIndex` | number | 05-rating-scale |
71
+ | `reverseScaleOrder` | boolean | 05-rating-scale |
69
72
 
70
73
  ## slider
71
74
 
72
- | Field | Values | Client file | Implemented? | Spec doc |
73
- |-------|--------|-------------|--------------|----------|
74
- | `min` / `max` / `step` | number | — | ❌ | 06-slider |
75
- | `defaultValue` | number | — | ❌ | 06-slider |
76
- | `minLabel` / `maxLabel` | string | — | ❌ | 06-slider |
77
- | `enableInputBox` | boolean | SliderMatrixScale.tsx | partial | 06-slider |
78
- | `displayValues` | boolean | CustomSliderTrack.tsx | partial | 06-slider, shared/custom-slider-track |
79
-
80
- ## matrix (shared)
81
-
82
- | Field | Values | Client file | Implemented? | Spec doc |
83
- |-------|--------|-------------|--------------|----------|
84
- | `subType` | CFM/CSAT/RATING | Question.tsx | ✅ | 07, 08 |
85
- | `rows[]` | MatrixRow[] | Likert/CsatMatrix | ✅ | 07, 08 |
86
- | `columns[]` | MatrixColumn[] | Likert/CsatMatrix | ✅ | 07, 08 |
87
- | `matrixFormat` | standard/carousel/dropdown | Likert/CsatMatrix | ✅ | 07, 08 |
88
- | `hasNotApplicable` | boolean | Likert/CsatMatrix | ✅ | 07, 08 |
89
- | `reverseScaleOrder` | boolean | CsatMatrixScale | ✅ | 08 |
90
- | `labels[]` | string[] | Likert/CsatMatrix | ✅ | 07, 08 |
91
- | `buttonType` | SurveyButtonType | CsatMatrixScale | ✅ | 08 |
92
-
93
- ## matrix CFM only
94
-
95
- | Field | Values | Client file | Implemented? | Spec doc |
96
- |-------|--------|-------------|--------------|----------|
97
- | `matrixType` | likert/bipolar | LikertMatrixScale | | 07-matrix-cfm |
98
- | `answerType` | single/multiple | LikertMatrixScale | ✅ | 07-matrix-cfm |
99
- | `transposeTable` | boolean | LikertMatrixScale | | 07-matrix-cfm |
100
- | `repeatScale` | boolean | LikertMatrixScale | ✅ | 07-matrix-cfm |
101
- | `enableScale` | boolean | LikertMatrixScale | ✅ | 07-matrix-cfm |
75
+ | Field | Values | Spec doc |
76
+ |-------|--------|----------|
77
+ | `min` / `max` / `step` | number | 06-slider |
78
+ | `defaultValue` | number | 06-slider |
79
+ | `minLabel` / `maxLabel` | string | 06-slider |
80
+ | `enableInputBox` | boolean | 06-slider |
81
+ | `displayValues` | boolean | 06-slider, shared/custom-slider-track |
82
+
83
+ ## cfm_matrix
84
+
85
+ | Field | Values | Spec doc |
86
+ |-------|--------|----------|
87
+ | `statementRows[]` | CfmMatrixStatementRow[] | 07-matrix-cfm |
88
+ | `scaleColumns[]` | CfmMatrixScaleColumn[] | 07-matrix-cfm |
89
+ | `statementLayout` | likert/bipolar | 07-matrix-cfm |
90
+ | `selectionMode` | single/multiple | 07-matrix-cfm |
91
+ | `gridLayout` | standard/carousel/dropdown | 07-matrix-cfm |
92
+ | `transposeTable` | boolean | 07-matrix-cfm |
93
+ | `repeatColumnHeaders` | boolean | 07-matrix-cfm |
94
+ | `showColumnHeaders` | boolean | 07-matrix-cfm |
95
+ | `hasNotApplicableOption` | boolean | 07-matrix-cfm |
96
+ | `scaleAnchorLabels[]` | string[] | 07-matrix-cfm |
97
+
98
+ ## rating_matrix
99
+
100
+ | Field | Values | Spec doc |
101
+ |-------|--------|----------|
102
+ | Same matrix fields as `csat` | | 08-matrix-csat-rating |
103
+ | `minLabel` / `maxLabel` | string | 08-matrix-csat-rating |
102
104
 
103
105
  ## slider_matrix
104
106
 
105
- | Field | Values | Client file | Implemented? | Spec doc |
106
- |-------|--------|-------------|--------------|----------|
107
- | `rows[].min/max/step` | number | SliderMatrixScale | ✅ | 09-slider-matrix |
108
- | `labels[]` | string[] | SliderMatrixScale | ✅ | 09-slider-matrix |
109
- | `ticks` | number | SliderMatrixScale | ✅ | 09-slider-matrix |
110
- | `tickValues[]` | TickValue[] | SliderMatrixScale | ✅ | 09-slider-matrix |
111
- | `enableInputBox` | boolean | SliderMatrixScale | ✅ | 09-slider-matrix |
112
- | `displayValues` | boolean | CustomSliderTrack | ✅ | 09-slider-matrix |
113
- | `enableNotApplicable` | boolean | SliderMatrixScale | ✅ | 09-slider-matrix |
114
- | `sliderType` | graphics | SliderMatrixScale | ✅ | 09-slider-matrix |
107
+ | Field | Values | Spec doc |
108
+ |-------|--------|----------|
109
+ | `statementRows[].min/max/step` | number | 09-slider-matrix |
110
+ | `scaleAnchorLabels[]` | string[] | 09-slider-matrix |
111
+ | `tickMarks` | number | 09-slider-matrix |
112
+ | `enableInputBox` | boolean | 09-slider-matrix |
113
+ | `displayValues` | boolean | 09-slider-matrix |
114
+ | `hasNotApplicableOption` | boolean | 09-slider-matrix |
115
+ | `sliderStyle` | graphics | 09-slider-matrix |
115
116
 
116
117
  ## file_upload
117
118
 
118
- | Field | Values | Client file | Implemented? | Spec doc |
119
- |-------|--------|-------------|--------------|----------|
120
- | `uploadMessage` | HTML string | FileUploadScale | ✅ | 10-file-upload |
121
- | `supportedFileFormats` | string[] | FileUploadScale | ✅ | 10-file-upload |
122
- | `maxFileCount` | number | FileUploadScale | ✅ | 10-file-upload |
123
- | `fileSizeLimit` | number (MB) | FileUploadScale | ✅ | 10-file-upload |
124
- | `fileSizeLimitType` | PER_FILE/IN_TOTAL | FileUploadScale | ✅ | 10-file-upload |
119
+ | Field | Values | Spec doc |
120
+ |-------|--------|----------|
121
+ | `uploadMessage` | HTML string | 10-file-upload |
122
+ | `supportedFileFormats` | string[] | 10-file-upload |
123
+ | `maxFileCount` | number | 10-file-upload |
124
+ | `fileSizeLimit` | number (MB) | 10-file-upload |
125
+ | `fileSizeLimitType` | PER_FILE/IN_TOTAL | 10-file-upload |
125
126
 
126
127
  ## text_and_media
127
128
 
128
- | Field | Values | Client file | Implemented? | Spec doc |
129
- |-------|--------|-------------|--------------|----------|
130
- | `mediaUrl` | string | Question.tsx | ✅ | 11-text-and-media |
131
- | `mediaMimeType` | string | Question.tsx | ✅ | 11-text-and-media |
132
- | `mediaTitle` | string | Question.tsx | ✅ | 11-text-and-media |
133
- | `mediaAlignment` | string | Question.tsx | ✅ | 11-text-and-media |
134
- | `mediaSize` | number (%) | Question.tsx | ✅ | 11-text-and-media |
135
-
136
- ## Implementation Gaps (no client branch yet)
137
-
138
- | Gap | SDK type/field | Extend from |
139
- |-----|----------------|-------------|
140
- | `rating_scale` dispatcher | `type: 'rating_scale'` | CsatScale star/emoji patterns |
141
- | `slider` dispatcher | `type: 'slider'` | CustomSliderTrack + SliderMatrixScale row |
142
- | `radio.isMultiSelect` | checkbox cards | 02-radio card styling |
143
- | `text.inputVariant: 'short'` | single-line input | 03-text focus tokens |
144
- | `rating.reverseScaleOrder` | reverse options array | 01-rating |
145
- | `rating.buttonVariant` | numbered clickable badges | 01-rating |
146
- | `csat.hasNotApplicable` / `reverseScaleOrder` | standalone CSAT | 04-csat, 08-matrix N/A |
147
- | `containerMedia*` on any type | container asset | 11-text-and-media media block |
148
-
149
- ## buttonType × matrixFormat Quick Reference
150
-
151
- | buttonType | matrixFormat | Layout component | Spec |
152
- |------------|--------------|------------------|------|
129
+ | Field | Values | Spec doc |
130
+ |-------|--------|----------|
131
+ | `media` | QuestionMedia? | 11-text-and-media |
132
+ | `media.url` | string | 11-text-and-media |
133
+ | `media.mimeType` | string | 11-text-and-media |
134
+ | `media.title` | string | 11-text-and-media |
135
+ | `media.alignment` | string | 11-text-and-media |
136
+ | `media.size` | number | 11-text-and-media |
137
+ | `mediaTitle` | string | 11-text-and-media |
138
+ | `mediaAlignment` | string | 11-text-and-media |
139
+ | `mediaSize` | number (%) | 11-text-and-media |
140
+
141
+ ## displayStyle × gridLayout Quick Reference
142
+
143
+ | displayStyle | gridLayout | Layout component | Spec |
144
+ |--------------|------------|------------------|------|
153
145
  | (CFM default) | standard | LikertMatrixGrid | 07 |
154
146
  | (CFM default) | carousel | LikertMatrixCarousel | 07 |
155
147
  | (CFM default) | dropdown | LikertMatrixDropdown | 07 |
156
- | emoji/star/numbered | standard | CsatMatrixGrid | 08 |
157
- | emoji/star/numbered/graphics | carousel | CsatMatrixCarousel | 08 |
158
- | dropdown/selectbox/radio | any | CsatMatrixVerticalList | 08 |
148
+ | emoji/star/numbered | standard | CsatMatrixGrid | 04 |
149
+ | emoji/star/numbered/graphics | carousel | CsatMatrixCarousel | 04 |
150
+ | dropdown/selectbox | any | CsatMatrixVerticalList | 04 |
151
+
152
+ ## Shared spec triggers
153
+
154
+ When these config values appear, also read `03-ui-specs/shared/`:
155
+
156
+ | Config | Read |
157
+ |--------|------|
158
+ | `gridLayout: dropdown` | `matrix-dropdown.md` |
159
+ | `displayStyle: dropdown` or `selectbox` | `matrix-dropdown.md` |
160
+ | `displayStyle: graphics` or `sliderStyle: graphics` | `custom-slider-track.md` |
@@ -0,0 +1,149 @@
1
+ # SDK Public Exports
2
+
3
+ > Import **only** from the package root. Never from `/src/` paths.
4
+
5
+ ```typescript
6
+ import {
7
+ useSurveySDK,
8
+ ACTIONS,
9
+ QUESTION_TYPE,
10
+ type SurveyAction,
11
+ type UseSurveySDKProps,
12
+ type UseSurveySDKReturn,
13
+ type Survey,
14
+ type SurveyQuestion,
15
+ type SurveyPage,
16
+ type SurveyLanguage,
17
+ type SurveyPhase,
18
+ type SpecialPage,
19
+ type SkipLogic,
20
+ type DisplayLogic,
21
+ type AnswerLogic,
22
+ type QuestionDisplayVariant,
23
+ type CustomFieldType,
24
+ type CustomFieldValue,
25
+ type CustomFieldValueMap,
26
+ type LogicConditionEntity,
27
+ type McqQuestion,
28
+ type McqOption,
29
+ type NpsQuestion,
30
+ type NpsScalePoint,
31
+ type CsatQuestion,
32
+ type CsatStatementRow,
33
+ type CsatScaleColumn,
34
+ type TextInputQuestion,
35
+ type CfmMatrixQuestion,
36
+ type CfmMatrixStatementRow,
37
+ type CfmMatrixScaleColumn,
38
+ type RatingMatrixQuestion,
39
+ type RatingMatrixStatementRow,
40
+ type RatingMatrixScaleColumn,
41
+ type SliderMatrixQuestion,
42
+ type SliderMatrixStatementRow,
43
+ type SliderMatrixTickMark,
44
+ type FileUploadQuestion,
45
+ type UploadedFile,
46
+ type TextAndMediaQuestion,
47
+ type HeatmapQuestion,
48
+ type HeatmapRegion,
49
+ type HeatmapClickPoint,
50
+ type HeatmapAnswer,
51
+ type RankOrderQuestion,
52
+ type RankOrderOption,
53
+ type RankOrderAnswers,
54
+ type AnswerValue,
55
+ type MatrixRowAnswers,
56
+ type SurveyAnswers,
57
+ type UploadedFileAnswer,
58
+ type StatementRow,
59
+ type ScaleColumn,
60
+ type ContainerMedia,
61
+ type QuestionMedia,
62
+ matrixColumnStoredValue,
63
+ resolveSurveyQuestionPlaceholders,
64
+ formatAnswerForDisplay,
65
+ resolveQuestionDisplayText,
66
+ applyQuestionDisplayVariants,
67
+ computeActivePathQuestionNumbers,
68
+ applyActivePathQuestionNumbers,
69
+ getVisibleStatementRowsForAnswers,
70
+ getVisibleMcqOptionsForAnswers,
71
+ getVisibleScaleColumnsForAnswers,
72
+ getVisibleMatrixItemsForAnswers,
73
+ getVisibleRankOrderOptionsForAnswers,
74
+ assignRankWithoutDuplicates,
75
+ buildRankOrderFromOrderedOptionIds,
76
+ getOrderedOptionIdsFromRanks,
77
+ normalizeRankOrderAnswers,
78
+ } from '@explorer02/cfm-survey-sdk'; // or @repo/sdk
79
+ ```
80
+
81
+ > **CSAT emoji UI** is **not** exported from the SDK. Implement emoji/star icons client-side (typically `react-icons`). See `03-ui-specs/04-csat.md`.
82
+
83
+ ## Hook contract (authoritative)
84
+
85
+ | Item | Value |
86
+ |------|-------|
87
+ | Answers field | `state.answers` (`SurveyAnswers`) |
88
+ | Custom fields | `options.customFieldValues` (`CustomFieldValueMap`) — stable ref; see [`custom-field-logic-and-navigation.md`](../00-integration/custom-field-logic-and-navigation.md) |
89
+ | Change action | `{ type: 'CHANGE', payload: { questionId, answerValue } }` |
90
+ | Navigation | `'START'`, `'NEXT'`, `'PREVIOUS'`, `'SUBMIT'` |
91
+ | Phase | `state.phase`, `state.specialPage`, `state.canGoBack`, `state.primaryButtonType` |
92
+
93
+ See `MANIFEST.json` `hookContract` and `00-integration/useSurveySDK.md`.
94
+
95
+ ## Question type literals
96
+
97
+ All **11** values of `question.type` (from `QUESTION_TYPE`):
98
+
99
+ `MCQ` · `TEXTFIELD` · `NPS_SCALE` · `CFM_MATRIX` · `CSAT_MATRIX` · `RATING_MATRIX` · `SLIDER_MATRIX` · `FILE_UPLOAD` · `TEXT_AND_MEDIA` · `HEATMAP` · `RANK_ORDER`
100
+
101
+ Dispatch with `question.type === QUESTION_TYPE.CSAT_MATRIX` (or string literal `'CSAT_MATRIX'`).
102
+
103
+ > **Note:** Legacy mapper types `star_rating` / `slider` are not in the `SurveyQuestion` union. API RATING/SLIDER pages map into `NPS_SCALE`, matrix display styles, or `SLIDER_MATRIX`.
104
+
105
+ See `MANIFEST.json` `typeLiterals` and [`question-type-sdk-matrix.md`](../00-integration/question-type-sdk-matrix.md) for routing to docs and components.
106
+
107
+ ## Value derivation
108
+
109
+ - Matrix storage: import `matrixColumnStoredValue` from the package root (do not reimplement).
110
+ - Rank order: `assignRankWithoutDuplicates`, `buildRankOrderFromOrderedOptionIds`, `getOrderedOptionIdsFromRanks`, `normalizeRankOrderAnswers`.
111
+ - Submit mapping: SDK derives API strings at submit/partial-save time — see [`value-derivation.md`](value-derivation.md).
112
+
113
+ ## Visibility helpers (answer logic UI)
114
+
115
+ Pass `customFieldValues` as the optional 4th argument when logic rules reference `CUSTOM_FIELD` entities:
116
+
117
+ ```typescript
118
+ getVisibleMcqOptionsForAnswers(question, answers, allQuestions, customFieldValues?);
119
+ getVisibleMatrixItemsForAnswers(question, answers, allQuestions, customFieldValues?);
120
+ getVisibleStatementRowsForAnswers(question, answers, allQuestions, customFieldValues?);
121
+ getVisibleScaleColumnsForAnswers(question, answers, allQuestions, customFieldValues?);
122
+ getVisibleRankOrderOptionsForAnswers(question, answers, allQuestions, customFieldValues?);
123
+ ```
124
+
125
+ See [`answer-logic-and-navigation.md`](../00-integration/answer-logic-and-navigation.md) and [`custom-field-logic-and-navigation.md`](../00-integration/custom-field-logic-and-navigation.md).
126
+
127
+ ## Question display variants
128
+
129
+ The SDK resolves conditional question text on `state.currentQuestions`. Clients render `question.questionText` as-is — no variant checks required. See [`question-display-variants.md`](../00-integration/question-display-variants.md).
130
+
131
+ Optional helpers: `resolveQuestionDisplayText`, `applyQuestionDisplayVariants`, type `QuestionDisplayVariant`.
132
+
133
+ ## Question numbering
134
+
135
+ Active-path ordinals are on `state.currentQuestions[].questionNumber`. Optional: `computeActivePathQuestionNumbers`, `applyActivePathQuestionNumbers`. See [`question-numbering.md`](../00-integration/question-numbering.md).
136
+
137
+ ## Related integration docs
138
+
139
+ - [`client-integration-guide.md`](../00-integration/client-integration-guide.md)
140
+ - [`question-type-sdk-matrix.md`](../00-integration/question-type-sdk-matrix.md)
141
+ - [`placeholders-and-tokens.md`](../00-integration/placeholders-and-tokens.md)
142
+ - [`partial-save-and-recovery.md`](../00-integration/partial-save-and-recovery.md)
143
+ - [`survey-lifecycle-analytics.md`](../00-integration/survey-lifecycle-analytics.md)
144
+ - [`skip-logic-and-navigation.md`](../00-integration/skip-logic-and-navigation.md)
145
+ - [`display-logic-and-navigation.md`](../00-integration/display-logic-and-navigation.md)
146
+ - [`question-display-variants.md`](../00-integration/question-display-variants.md)
147
+ - [`question-numbering.md`](../00-integration/question-numbering.md)
148
+ - [`answer-logic-and-navigation.md`](../00-integration/answer-logic-and-navigation.md)
149
+ - [`progress.md`](../00-integration/progress.md)
@@ -1,52 +1,51 @@
1
- # Rating Question (NPS 0-10)
1
+ # NPS Question (010)
2
2
 
3
- > **Type**: `'rating'` | **API Source**: `SCALE` with `SCALE_TYPE=TEN_POINT` or `NPS_SCALE`
4
- > **Mapper**: `ratingMapper.ts` | **Component**: `RatingScale`
3
+ > **Type**: `'NPS_SCALE'` | **API Source**: `SCALE` / `NPS_SCALE`
4
+ > **SDK type file**: `fetchSurvey/types/nps.ts` | **Component**: `RatingScale`
5
5
 
6
6
  ## TypeScript Type
7
7
 
8
8
  ```typescript
9
- type RatingQuestion = QuestionBase & {
10
- type: 'rating';
11
- options: SurveyOption[]; // 0-10 with NPS traffic-light colors
12
- minLabel?: string; // Left label (e.g. "Not Likely")
13
- midLabel?: string; // Middle label (e.g. "Neutral")
14
- maxLabel?: string; // Right label (e.g. "Extremely Likely")
15
- midLabelIndex?: number; // Fractional position for mid-label CSS
16
- reverseScaleOrder?: boolean; // Render high→low
17
- buttonVariant?: 'radio' | 'numbered' | 'emoji';
9
+ type NpsQuestion = {
10
+ type: 'NPS_SCALE';
11
+ id: string;
12
+ questionText: string;
13
+ questionDescription?: string;
14
+ options: NpsScalePoint[];
15
+ minLabel?: string;
16
+ midLabel?: string;
17
+ maxLabel?: string;
18
+ midLabelIndex?: number;
19
+ reverseScaleOrder: boolean;
20
+ buttonStyle: 'standard' | 'numbered' | 'emoji';
21
+ required: boolean;
22
+ // ... shell fields
18
23
  };
19
24
  ```
20
25
 
21
26
  ## Answer Shape: `number`
22
- Example: `7` (the selected badge value)
23
-
24
- ## Options Auto-Generation
25
- If the API provides no explicit options, the SDK generates 0-10:
26
- ```typescript
27
- Array.from({ length: 11 }, (_, i) => ({
28
- id: String(i), label: String(i), value: i, color: getColor(i)
29
- }));
30
- ```
31
27
 
32
- ## NPS Traffic-Light Colors
33
- ```
34
- 0: #e2001a (red) 3: #f18b00 (orange) 6: #fcd900 (yellow)
35
- 1: #e4251b 4: #f7b200 7: #9fca00 (lime)
36
- 2: #ec610a 5: #fcd900 8: #6bb300 (green)
37
- 9: #339a00
38
- 10: #008000
39
- ```
28
+ Example: `7` (the selected badge value)
40
29
 
41
30
  ## Mid-Label Positioning
31
+
42
32
  ```typescript
43
- // CSS left percentage for mid-label
44
33
  const left = (midLabelIndex / (options.length - 1)) * 100;
45
- // For 11-point scale: midLabelIndex defaults to 7.5
46
34
  ```
47
35
 
48
36
  ## Rendering Guidance
37
+
49
38
  - Display as horizontal row of numbered badge buttons
50
- - Each badge uses `option.color` as background
51
39
  - Selected badge: emphasized border/scale, all others dimmed
52
40
  - Labels positioned: minLabel (left), midLabel (calculated %), maxLabel (right)
41
+
42
+ ## SDK Integration Checklist (agent)
43
+
44
+ - [ ] Type literal: `QUESTION_TYPE.NPS_SCALE`
45
+ - [ ] Answer stored as: `number` (selected scale point value)
46
+ - [ ] onAction CHANGE payload: `{ questionId, answerValue: number }`
47
+ - [ ] Visibility helper: `getVisibleScaleColumnsForAnswers` when scale points have answer logic
48
+ - [ ] Custom fields: pass `customFieldValues` as 4th arg to scale visibility helper when rules reference CRM fields
49
+ - [ ] Logic features: skip ✓ display ✓ answer ✓ (columns) variants ✓ numbering ✓
50
+ - [ ] Performance: single horizontal row — no matrix filtering overhead
51
+ - [ ] Matrix row: [`question-type-sdk-matrix.md#nps_scale`](../../00-integration/question-type-sdk-matrix.md#nps_scale)
@@ -1,54 +1,63 @@
1
- # CSAT Question (Satisfaction Scale)
1
+ # CSAT Matrix Question (Satisfaction Grid)
2
2
 
3
- > **Type**: `'csat'` | **API Source**: `SCALE` with `SCALE_TYPE=CSAT` or ≤5 options
4
- > **Mapper**: `ratingMapper.ts` (CSAT branch) | **Component**: `CsatScale`
3
+ > **Type**: `'CSAT_MATRIX'` | **API Source**: `CSAT_MATRIX`
4
+ > **SDK type**: `CsatQuestion` | **Component**: `CsatMatrixScale`
5
5
 
6
6
  ## TypeScript Type
7
7
 
8
8
  ```typescript
9
- type CsatQuestion = QuestionBase & {
10
- type: 'csat';
11
- options: SurveyOption[]; // Usually 1-5 satisfaction levels
12
- minLabel?: string; // "Very Dissatisfied"
13
- maxLabel?: string; // "Very Satisfied"
14
- buttonType?: SurveyButtonType; // 'emoji' | 'star' | 'numbered' | 'radio'
15
- hasNotApplicable?: boolean; // N/A option available
16
- reverseScaleOrder?: boolean; // Render high→low
17
- labelPosition?: 'top' | 'bottom' | 'hidden';
9
+ type CsatQuestion = {
10
+ type: 'CSAT_MATRIX';
11
+ id: string;
12
+ statementRows: CsatStatementRow[];
13
+ scaleColumns: CsatScaleColumn[];
14
+ displayStyle: 'emoji' | 'star' | 'standard' | 'numbered' | 'dropdown' | 'selectbox' | 'graphics';
15
+ gridLayout: 'standard' | 'carousel' | 'dropdown';
16
+ hasNotApplicableOption: boolean;
17
+ reverseScaleOrder: boolean;
18
+ // ... shell fields, skipLogics?, displayLogic?
18
19
  };
20
+
21
+ type CsatStatementRow = { id: string; statementText: string; answerLogic?: AnswerLogic };
22
+ type CsatScaleColumn = { id: string; label: string; answerLogic?: AnswerLogic };
19
23
  ```
20
24
 
21
- ## Answer Shape: `number | null`
22
- Example: `4` or `null` (N/A selected)
25
+ Filter visible rows/columns with `getVisibleMatrixItemsForAnswers` before rendering (see [`answer-logic-and-navigation.md`](../../00-integration/answer-logic-and-navigation.md)).
23
26
 
24
- ## Rendering by `buttonType`
27
+ ## Answer Shape: `MatrixRowAnswers`
25
28
 
26
- | `buttonType` | Render As |
27
- |-------------|-----------|
28
- | `'emoji'` | Sentiment face icons from `CsatEmojiMapping` |
29
- | `'star'` | Star icons from `CsatStarIcons` (filled/empty) |
30
- | `'numbered'` | Numeric badge buttons |
31
- | `'radio'` | Standard radio circles |
32
- | `'graphics'` | Emoji slider (use `CustomSliderTrack`) |
33
-
34
- ## Star Rating Pattern
35
- ```tsx
36
- {options.map((opt, i) => {
37
- const numericValue = typeof opt.value === 'number' ? opt.value : i + 1;
38
- const isActive = typeof selectedValue === 'number' && numericValue <= selectedValue;
39
- return (
40
- <button onClick={() => onSelect(opt.value)}>
41
- {isActive ? CsatStarIcons.filled : CsatStarIcons.empty}
42
- </button>
43
- );
44
- })}
45
- ```
29
+ Store column **`id`** per row (not label text):
46
30
 
47
- ## Emoji Pattern
48
- ```tsx
49
- {options.map((opt, i) => (
50
- <button onClick={() => onSelect(opt.value)}>
51
- {CsatEmojiMapping[typeof opt.value === 'number' ? opt.value : i + 1]}
52
- </button>
53
- ))}
31
+ ```typescript
32
+ import { matrixColumnStoredValue } from '@explorer02/cfm-survey-sdk';
33
+
34
+ // { [rowId]: columnId | columnId[] | null }
35
+ { "row_1": "col_5", "row_2": null }
54
36
  ```
37
+
38
+ Submit maps ids → API label/number via SDK `resolveSubmitValues`.
39
+
40
+ ## Rendering by `displayStyle`
41
+
42
+ | `displayStyle` | Cell Rendering |
43
+ |----------------|----------------|
44
+ | `'emoji'` | Sentiment faces — implement client-side with `react-icons` (not SDK exports) |
45
+ | `'star'` | Star icons — implement client-side with `react-icons` |
46
+ | `'numbered'` | Numeric badge buttons |
47
+ | `'dropdown'` | Dropdown per row (`MatrixDropdown`) |
48
+ | `'graphics'` | Emoji slider per row (`CustomSliderTrack`) |
49
+
50
+ ## N/A Column
51
+
52
+ When `hasNotApplicableOption` is true, selecting N/A stores `null` for that row — a valid answer.
53
+
54
+ ## SDK Integration Checklist (agent)
55
+
56
+ - [ ] Type literal: `QUESTION_TYPE.CSAT_MATRIX`
57
+ - [ ] Answer stored as: `MatrixRowAnswers` — column **`id`** per row via `matrixColumnStoredValue`
58
+ - [ ] onAction CHANGE payload: `{ questionId, answerValue: MatrixRowAnswers }` (merge row updates)
59
+ - [ ] Visibility helper: `getVisibleMatrixItemsForAnswers(question, answers, allQuestions, customFieldValues?)`
60
+ - [ ] Custom fields: 4th arg on matrix visibility helper when logic references CRM fields
61
+ - [ ] Logic features: skip ✓ display ✓ answer ✓ (rows + columns) variants ✓ numbering ✓
62
+ - [ ] Performance: render only visible rows/cols; memoize emoji/star maps for graphics mode
63
+ - [ ] Matrix row: [`question-type-sdk-matrix.md#csat_matrix`](../../00-integration/question-type-sdk-matrix.md#csat_matrix)