@explorer02/cfm-survey-sdk 0.2.1 → 0.2.3
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 +18 -18
- package/dist/cli/index.mjs +14 -14
- package/dist/index.d.mts +465 -580
- package/dist/index.d.ts +465 -580
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +6 -4
- package/postinstall.js +96 -69
- package/templates/AGENT.md +18 -8
- package/templates/docs/00-integration/analytics-events-catalog.md +54 -0
- package/templates/docs/00-integration/answer-logic-and-navigation.md +50 -0
- package/templates/docs/00-integration/aws-deploy.md +281 -0
- package/templates/docs/00-integration/client-integration-guide.md +351 -0
- package/templates/docs/00-integration/component-checklist.md +55 -22
- package/templates/docs/00-integration/constraints.md +49 -4
- package/templates/docs/00-integration/custom-field-logic-and-navigation.md +174 -0
- package/templates/docs/00-integration/display-logic-and-navigation.md +64 -0
- package/templates/docs/00-integration/end-page-logic.md +64 -0
- package/templates/docs/00-integration/file-upload-aws.md +116 -0
- package/templates/docs/00-integration/logic-fields-catalog.md +105 -0
- package/templates/docs/00-integration/partial-save-and-recovery.md +98 -0
- package/templates/docs/00-integration/placeholders-and-tokens.md +116 -0
- package/templates/docs/00-integration/progress.md +61 -0
- package/templates/docs/00-integration/question-display-variants.md +65 -0
- package/templates/docs/00-integration/question-numbering.md +51 -0
- package/templates/docs/00-integration/question-type-sdk-matrix.md +244 -0
- package/templates/docs/00-integration/setup.md +84 -0
- package/templates/docs/00-integration/skip-logic-and-navigation.md +80 -0
- package/templates/docs/00-integration/survey-lifecycle-analytics.md +94 -0
- package/templates/docs/00-integration/useSurveySDK.md +151 -23
- package/templates/docs/01-components/01-survey-page.md +76 -54
- package/templates/docs/01-components/02-question.md +61 -58
- package/templates/docs/01-components/03-rating-scale.md +11 -1
- package/templates/docs/01-components/04-star-rating-scale.md +45 -0
- package/templates/docs/01-components/05-csat-matrix-scale.md +20 -11
- package/templates/docs/01-components/06-likert-matrix-scale.md +14 -4
- package/templates/docs/01-components/07-slider-matrix-scale.md +11 -2
- package/templates/docs/01-components/08-file-upload-scale.md +23 -51
- package/templates/docs/01-components/09-custom-slider-track.md +2 -2
- package/templates/docs/01-components/11-progress-bar.md +10 -4
- package/templates/docs/01-components/13-matrix-dropdown.md +29 -32
- package/templates/docs/01-components/14-intro-page.md +34 -0
- package/templates/docs/01-components/15-end-page.md +31 -0
- package/templates/docs/01-components/16-paused-page.md +27 -0
- package/templates/docs/01-components/17-heatmap-scale.md +75 -0
- package/templates/docs/01-components/18-rank-order-scale.md +93 -0
- package/templates/docs/01-components/README.md +42 -36
- package/templates/docs/02-reference/config-field-index.md +141 -139
- package/templates/docs/02-reference/exports.md +149 -0
- package/templates/docs/02-reference/question-types/01-rating.md +31 -32
- package/templates/docs/02-reference/question-types/04-csat.md +51 -42
- package/templates/docs/02-reference/question-types/05-rating-scale.md +16 -11
- package/templates/docs/02-reference/question-types/06-slider.md +2 -2
- package/templates/docs/02-reference/question-types/07-matrix-cfm.md +44 -30
- package/templates/docs/02-reference/question-types/08-matrix-csat.md +4 -26
- package/templates/docs/02-reference/question-types/09-matrix-rating.md +29 -13
- package/templates/docs/02-reference/question-types/10-slider-matrix.md +15 -4
- package/templates/docs/02-reference/question-types/11-file-upload.md +43 -17
- package/templates/docs/02-reference/question-types/12-heatmap.md +59 -0
- package/templates/docs/02-reference/question-types/13-rank-order.md +101 -0
- package/templates/docs/02-reference/question-types/README.md +96 -47
- package/templates/docs/02-reference/routing-table.md +33 -18
- package/templates/docs/02-reference/value-derivation.md +63 -0
- package/templates/docs/03-ui-specs/00-question-shell.md +19 -88
- package/templates/docs/03-ui-specs/01-rating.md +18 -52
- package/templates/docs/03-ui-specs/02-radio.md +80 -37
- package/templates/docs/03-ui-specs/03-text.md +2 -2
- package/templates/docs/03-ui-specs/04-csat.md +68 -33
- package/templates/docs/03-ui-specs/05-rating-scale.md +21 -18
- package/templates/docs/03-ui-specs/06-slider.md +3 -1
- package/templates/docs/03-ui-specs/07-matrix-cfm.md +44 -25
- package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +19 -43
- package/templates/docs/03-ui-specs/09-slider-matrix.md +18 -1
- package/templates/docs/03-ui-specs/10-file-upload.md +42 -21
- package/templates/docs/03-ui-specs/11-text-and-media.md +29 -29
- package/templates/docs/03-ui-specs/12-survey-chrome.md +58 -14
- package/templates/docs/03-ui-specs/13-heatmap.md +80 -0
- package/templates/docs/03-ui-specs/14-rank-order.md +128 -0
- package/templates/docs/03-ui-specs/README.md +16 -14
- package/templates/docs/03-ui-specs/shared/custom-slider-track.md +28 -35
- package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +5 -0
- package/templates/docs/MANIFEST.json +476 -69
- package/templates/docs/index.md +82 -30
- package/templates/docs/templates/CustomSliderTrack.tsx +144 -0
- package/templates/docs/templates/MatrixDropdown.tsx +216 -0
- package/templates/docs/templates/Question.tsx +221 -154
- package/templates/docs/templates/RankOrderScale.tsx +353 -0
- package/templates/docs/templates/deploy-to-aws.sh +114 -0
- package/templates/docs/templates/heatmapCoords.ts +58 -0
- package/templates/docs/templates/implementation_plan.md +126 -67
- package/templates/docs/templates/survey-inventory.schema.json +77 -0
- package/templates/docs/templates/surveyUiIcons.tsx +52 -0
- package/templates/docs/templates/verify-agent-build.sh +85 -0
- package/templates/docs/01-components/04-csat-scale.md +0 -40
- package/templates/docs/02-question-types/01-rating.md +0 -44
|
@@ -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
|
-
#
|
|
1
|
+
# NPS Question (0–10)
|
|
2
2
|
|
|
3
|
-
> **Type**: `'
|
|
4
|
-
> **
|
|
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
|
|
10
|
-
type: '
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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
|
|
1
|
+
# CSAT Matrix Question (Satisfaction Grid)
|
|
2
2
|
|
|
3
|
-
> **Type**: `'
|
|
4
|
-
> **
|
|
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 =
|
|
10
|
-
type: '
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
27
|
+
## Answer Shape: `MatrixRowAnswers`
|
|
25
28
|
|
|
26
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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)
|
|
@@ -1,26 +1,31 @@
|
|
|
1
|
-
# Rating
|
|
1
|
+
# Star Rating Question (Stars/Emoji)
|
|
2
2
|
|
|
3
|
-
> **Type**: `'
|
|
4
|
-
> **
|
|
3
|
+
> **Type**: `'star_rating'` | **API Source**: page `RATING`
|
|
4
|
+
> **SDK type file**: `fetchSurvey/types/starRating.ts` | **Component**: `RatingScale`
|
|
5
5
|
|
|
6
6
|
## TypeScript Type
|
|
7
7
|
|
|
8
8
|
```typescript
|
|
9
|
-
type
|
|
10
|
-
type: '
|
|
11
|
-
|
|
9
|
+
type StarRatingQuestion = {
|
|
10
|
+
type: 'star_rating';
|
|
11
|
+
id: string;
|
|
12
|
+
questionText: string;
|
|
13
|
+
options: StarRatingPoint[];
|
|
12
14
|
minLabel?: string;
|
|
13
15
|
midLabel?: string;
|
|
14
16
|
maxLabel?: string;
|
|
15
17
|
midLabelIndex?: number;
|
|
16
|
-
reverseScaleOrder
|
|
17
|
-
scaleStyle
|
|
18
|
+
reverseScaleOrder: boolean;
|
|
19
|
+
scaleStyle: 'star' | 'emoji';
|
|
20
|
+
required: boolean;
|
|
21
|
+
// ... shell fields
|
|
18
22
|
};
|
|
19
23
|
```
|
|
20
24
|
|
|
21
25
|
## Answer Shape: `number`
|
|
22
26
|
|
|
23
|
-
## Key Difference from `'
|
|
27
|
+
## Key Difference from `'nps'`
|
|
28
|
+
|
|
24
29
|
- No NPS traffic-light colors on options
|
|
25
|
-
- Rendered as stars
|
|
26
|
-
-
|
|
30
|
+
- Rendered as stars or emojis per `scaleStyle`
|
|
31
|
+
- See `03-ui-specs/05-rating-scale.md`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Slider Question (Single Range)
|
|
2
2
|
|
|
3
|
-
> **Type**: `'slider'` | **API Source**:
|
|
4
|
-
> **Mapper**: `
|
|
3
|
+
> **Type**: `'slider'` | **API Source**: page `SLIDER`
|
|
4
|
+
> **Mapper**: `sliderMapper.ts` | **Component**: `CustomSliderTrack` or native `<input type="range">`
|
|
5
5
|
|
|
6
6
|
## TypeScript Type
|
|
7
7
|
|
|
@@ -1,43 +1,57 @@
|
|
|
1
|
-
# Matrix
|
|
1
|
+
# CFM Matrix Question (Likert Grid)
|
|
2
2
|
|
|
3
|
-
> **Type**: `'
|
|
4
|
-
> **
|
|
3
|
+
> **Type**: `'CFM_MATRIX'` | **API Source**: `CFM_MATRIX`
|
|
4
|
+
> **SDK type file**: `fetchSurvey/types/cfmMatrix.ts` | **Component**: `LikertMatrixScale`
|
|
5
5
|
|
|
6
6
|
## TypeScript Type
|
|
7
7
|
|
|
8
8
|
```typescript
|
|
9
|
-
type
|
|
10
|
-
type: '
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
type CfmMatrixQuestion = {
|
|
10
|
+
type: 'CFM_MATRIX';
|
|
11
|
+
id: string;
|
|
12
|
+
questionText: string;
|
|
13
|
+
statementRows: CfmMatrixStatementRow[];
|
|
14
|
+
scaleColumns: CfmMatrixScaleColumn[];
|
|
15
|
+
statementLayout: 'likert' | 'bipolar';
|
|
16
|
+
selectionMode: 'single' | 'multiple';
|
|
17
|
+
gridLayout: 'standard' | 'carousel' | 'dropdown';
|
|
18
|
+
transposeTable: boolean;
|
|
19
|
+
repeatColumnHeaders: boolean;
|
|
20
|
+
hasNotApplicableOption: boolean;
|
|
21
|
+
showColumnHeaders: boolean;
|
|
22
|
+
scaleAnchorLabels?: string[];
|
|
23
|
+
required: boolean;
|
|
24
|
+
// ... shell fields
|
|
24
25
|
};
|
|
25
26
|
|
|
26
|
-
type
|
|
27
|
-
|
|
27
|
+
type CfmMatrixStatementRow = {
|
|
28
|
+
id: string;
|
|
29
|
+
statementText: string;
|
|
30
|
+
oppositeStatementText?: string;
|
|
31
|
+
};
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
## Answer Shape: `
|
|
34
|
+
## Answer Shape: `MatrixRowAnswers`
|
|
35
|
+
|
|
31
36
|
```typescript
|
|
32
|
-
{ "row1_id":
|
|
33
|
-
// null = N/A selected for that row
|
|
37
|
+
{ "row1_id": columnValue, "row2_id": null }
|
|
34
38
|
```
|
|
35
39
|
|
|
36
40
|
## Rendering Guidance
|
|
37
|
-
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
|
|
41
|
+
|
|
42
|
+
- **standard**: Grid table — rows on left, columns as headers
|
|
43
|
+
- **carousel**: One row at a time with prev/next
|
|
44
|
+
- **dropdown**: Each row has a dropdown (`MatrixDropdown`)
|
|
45
|
+
- **bipolar**: `statementText` left + `oppositeStatementText` right
|
|
46
|
+
- `onSelect` receives the full `MatrixRowAnswers` object on each change
|
|
47
|
+
|
|
48
|
+
## SDK Integration Checklist (agent)
|
|
49
|
+
|
|
50
|
+
- [ ] Type literal: `QUESTION_TYPE.CFM_MATRIX`
|
|
51
|
+
- [ ] Answer stored as: `MatrixRowAnswers` — column **`id`** via `matrixColumnStoredValue`
|
|
52
|
+
- [ ] onAction CHANGE payload: `{ questionId, answerValue: MatrixRowAnswers }`
|
|
53
|
+
- [ ] Visibility helper: `getVisibleMatrixItemsForAnswers(question, answers, allQuestions, customFieldValues?)`
|
|
54
|
+
- [ ] Custom fields: 4th arg on matrix visibility helper when logic references CRM fields
|
|
55
|
+
- [ ] Logic features: skip ✓ display ✓ answer ✓ (rows + columns) variants ✓ numbering ✓
|
|
56
|
+
- [ ] Performance: filter rows/cols before render; lazy-load large matrices
|
|
57
|
+
- [ ] Matrix row: [`question-type-sdk-matrix.md#cfm_matrix`](../../00-integration/question-type-sdk-matrix.md#cfm_matrix)
|
|
@@ -1,29 +1,7 @@
|
|
|
1
|
-
# Matrix
|
|
1
|
+
# CSAT Matrix Question (legacy reference)
|
|
2
2
|
|
|
3
|
-
> **
|
|
4
|
-
> **Mapper**: `csatMatrixMapper.ts` | **Component**: `CsatMatrixScale`
|
|
3
|
+
> **Deprecated alias.** CSAT matrix grids use `type: 'CSAT_MATRIX'` — see [04-csat.md](04-csat.md).
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
Same as `MatrixQuestion` (see `07-matrix-cfm.md`) but with `subType: 'CSAT_MATRIX'`.
|
|
5
|
+
For rating-style matrix grids use `type: 'RATING_MATRIX'` — see [09-matrix-rating.md](09-matrix-rating.md).
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
- Columns represent satisfaction levels (not text labels)
|
|
11
|
-
- Uses `buttonType` to determine visual: emoji faces, stars, numbered, etc.
|
|
12
|
-
- Uses `getEmojiForIndex(colIndex, totalCols)` for emoji rendering per cell
|
|
13
|
-
|
|
14
|
-
## Rendering by `buttonType`
|
|
15
|
-
|
|
16
|
-
| `buttonType` | Cell Rendering |
|
|
17
|
-
|-------------|---------------|
|
|
18
|
-
| `'emoji'` | Sentiment face icons via `getEmojiForIndex` |
|
|
19
|
-
| `'star'` | Star icons via `CsatStarIcons` |
|
|
20
|
-
| `'numbered'` | Numeric badge buttons |
|
|
21
|
-
| `'radio'` | Standard radio circles |
|
|
22
|
-
| `'dropdown'` | Dropdown per row (uses `MatrixDropdown`) |
|
|
23
|
-
| `'graphics'` | Emoji slider per row (uses `CustomSliderTrack`) |
|
|
24
|
-
|
|
25
|
-
## Answer Shape: `MatrixAnswerMap`
|
|
26
|
-
Same as CFM_MATRIX — `{ "row_id": column_value | null }`
|
|
27
|
-
|
|
28
|
-
## N/A Column
|
|
29
|
-
If `hasNotApplicable` is true, the last column has `value: null`. Selecting it records `null` for that row, which is a valid answer (passes validation).
|
|
7
|
+
There is no `subType` field. Each matrix variant is a flat `question.type` literal.
|
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
# Rating Matrix Question
|
|
2
2
|
|
|
3
|
-
> **Type**: `'
|
|
4
|
-
> **
|
|
3
|
+
> **Type**: `'RATING_MATRIX'` | **API Source**: `RATING_MATRIX`
|
|
4
|
+
> **Component**: `CsatMatrixScale`
|
|
5
5
|
|
|
6
6
|
## TypeScript Type
|
|
7
7
|
|
|
8
8
|
```typescript
|
|
9
|
-
type RatingMatrixQuestion =
|
|
10
|
-
type: '
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
type RatingMatrixQuestion = {
|
|
10
|
+
type: 'RATING_MATRIX';
|
|
11
|
+
statementRows: StatementRow[];
|
|
12
|
+
scaleColumns: ScaleColumn[];
|
|
13
13
|
minLabel?: string;
|
|
14
14
|
maxLabel?: string;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
displayStyle: CsatQuestion['displayStyle'];
|
|
16
|
+
gridLayout: 'standard' | 'carousel' | 'dropdown';
|
|
17
|
+
hasNotApplicableOption: boolean;
|
|
18
|
+
reverseScaleOrder: boolean;
|
|
19
|
+
scaleAnchorLabels?: string[];
|
|
20
|
+
// + shell fields (id, questionText, required, containerMedia?, etc.)
|
|
19
21
|
};
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
## Key Difference from CSAT_MATRIX
|
|
23
|
-
|
|
25
|
+
|
|
24
26
|
- Has `minLabel`/`maxLabel` endpoint labels
|
|
27
|
+
- Column badge colors derived client-side via `columnAccentColor(col)` — see `02-reference/value-derivation.md`
|
|
25
28
|
- Rendered by the same `CsatMatrixScale` component
|
|
26
29
|
|
|
27
|
-
## Answer Shape: `
|
|
28
|
-
|
|
30
|
+
## Answer Shape: `MatrixRowAnswers`
|
|
31
|
+
|
|
32
|
+
`Record<statementRows[].id, matrixColumnStoredValue(col) | null>` — stored value is always the column **`id`**; submit maps id → label/number via `resolveSubmitValues`.
|
|
33
|
+
|
|
34
|
+
## SDK Integration Checklist (agent)
|
|
35
|
+
|
|
36
|
+
- [ ] Type literal: `QUESTION_TYPE.RATING_MATRIX`
|
|
37
|
+
- [ ] Answer stored as: `MatrixRowAnswers` — column **`id`** via `matrixColumnStoredValue`
|
|
38
|
+
- [ ] onAction CHANGE payload: `{ questionId, answerValue: MatrixRowAnswers }`
|
|
39
|
+
- [ ] Visibility helper: `getVisibleMatrixItemsForAnswers(question, answers, allQuestions, customFieldValues?)`
|
|
40
|
+
- [ ] Custom fields: 4th arg on matrix visibility helper when logic references CRM fields
|
|
41
|
+
- [ ] Logic features: skip ✓ display ✓ answer ✓ (rows; column logic may be limited) variants ✓ numbering ✓
|
|
42
|
+
- [ ] Performance: reuse `CsatMatrixScale`; render only visible rows/cols
|
|
43
|
+
- [ ] Known limitation: column-level answer logic gap — verify fetched survey rules
|
|
44
|
+
- [ ] Matrix row: [`question-type-sdk-matrix.md#rating_matrix`](../../00-integration/question-type-sdk-matrix.md#rating_matrix)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Slider Matrix Question
|
|
2
2
|
|
|
3
|
-
> **Type**: `'
|
|
3
|
+
> **Type**: `'SLIDER_MATRIX'` | **API Source**: `SLIDER_MATRIX`
|
|
4
4
|
> **Mapper**: `sliderMatrixMapper.ts` | **Component**: `SliderMatrixScale`
|
|
5
5
|
|
|
6
6
|
## TypeScript Type
|
|
7
7
|
|
|
8
8
|
```typescript
|
|
9
9
|
type SliderMatrixQuestion = QuestionBase & {
|
|
10
|
-
type: '
|
|
10
|
+
type: 'SLIDER_MATRIX';
|
|
11
11
|
rows: SliderMatrixRow[]; // Each row has independent slider config
|
|
12
12
|
labels?: string[]; // Anchor labels above track
|
|
13
13
|
ticks?: number; // Number of tick marks (default 10)
|
|
@@ -25,7 +25,7 @@ type SliderMatrixRow = MatrixRow & {
|
|
|
25
25
|
type TickValue = { value: number; label: string; color: string; };
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
## Answer Shape: `
|
|
28
|
+
## Answer Shape: `MatrixRowAnswers`
|
|
29
29
|
```typescript
|
|
30
30
|
{ "row1_id": 75, "row2_id": 30, "row3_id": null }
|
|
31
31
|
// number = slider position, null = N/A
|
|
@@ -37,4 +37,15 @@ type TickValue = { value: number; label: string; color: string; };
|
|
|
37
37
|
- If `tickValues` available → render tick marks with labels and colors
|
|
38
38
|
- If `enableInputBox` → show numeric input alongside slider
|
|
39
39
|
- If `enableNotApplicable` → add N/A checkbox per row
|
|
40
|
-
- `onSelect` receives the full `
|
|
40
|
+
- `onSelect` receives the full `MatrixRowAnswers` with all row values
|
|
41
|
+
|
|
42
|
+
## SDK Integration Checklist (agent)
|
|
43
|
+
|
|
44
|
+
- [ ] Type literal: `QUESTION_TYPE.SLIDER_MATRIX`
|
|
45
|
+
- [ ] Answer stored as: `MatrixRowAnswers` — numeric slider value or `null` for N/A per row
|
|
46
|
+
- [ ] onAction CHANGE payload: `{ questionId, answerValue: MatrixRowAnswers }`
|
|
47
|
+
- [ ] Visibility helper: `getVisibleStatementRowsForAnswers(question, answers, allQuestions, customFieldValues?)`
|
|
48
|
+
- [ ] Custom fields: 4th arg on statement-row helper when logic references CRM fields
|
|
49
|
+
- [ ] Logic features: skip ✓ display ✓ answer ✓ (rows) variants ✓ numbering ✓
|
|
50
|
+
- [ ] Performance: debounce drag events if partial save enabled; one slider per visible row
|
|
51
|
+
- [ ] Matrix row: [`question-type-sdk-matrix.md#slider_matrix`](../../00-integration/question-type-sdk-matrix.md#slider_matrix)
|