@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
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* Enum representing all action types supported by the survey SDK dispatcher.
|
|
5
3
|
*/
|
|
@@ -7,650 +5,510 @@ declare enum ACTIONS {
|
|
|
7
5
|
NEXT = "NEXT",
|
|
8
6
|
PREVIOUS = "PREVIOUS",
|
|
9
7
|
SUBMIT = "SUBMIT",
|
|
10
|
-
|
|
8
|
+
START = "START",
|
|
9
|
+
CHANGE = "CHANGE",
|
|
10
|
+
SCROLL = "SCROLL",
|
|
11
|
+
RECORD_QUESTION_VIEW = "RECORD_QUESTION_VIEW"
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* - `'emoji'` — Sentiment emoji faces (😞 → 😐 → 😊)
|
|
18
|
-
* - `'star'` — Star icons (☆ → ★)
|
|
19
|
-
* - `'radio'` — Standard radio-button circles
|
|
20
|
-
* - `'numbered'` — Numeric badge buttons (1, 2, 3 …)
|
|
21
|
-
* - `'number'` — Alias for `'numbered'` (legacy value from API)
|
|
22
|
-
* - `'dropdown'` — Collapsed select dropdown
|
|
23
|
-
* - `'selectbox'` — Expanded list of selectable cards
|
|
24
|
-
* - `'graphics'` — Continuous slider with emoji thumb
|
|
25
|
-
*/
|
|
26
|
-
type SurveyButtonType = 'emoji' | 'star' | 'radio' | 'numbered' | 'number' | 'dropdown' | 'selectbox' | 'graphics';
|
|
27
|
-
/**
|
|
28
|
-
* A single selectable option used by rating, radio, CSAT, and matrix question types.
|
|
29
|
-
*/
|
|
30
|
-
type SurveyOption = {
|
|
31
|
-
/**
|
|
32
|
-
* Unique identifier for this option, sourced from the API's `answerDetail.id`.
|
|
33
|
-
* Falls back to the option's index position as a string if the API omits it.
|
|
34
|
-
*/
|
|
14
|
+
/** Logic filter and rule types shared by skip logic and display logic. */
|
|
15
|
+
type LogicFilterValue = string | number;
|
|
16
|
+
type CustomFieldType = 'TEXT' | 'TEXT_MULTI' | 'TEXTAREA' | 'NUMBER' | 'PICKLIST' | 'PICKLIST_MULTISELECT' | 'DATETIME';
|
|
17
|
+
type LogicConditionEntity = {
|
|
35
18
|
id: string;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
19
|
+
entityType: 'QUESTION';
|
|
20
|
+
answerType?: string;
|
|
21
|
+
} | {
|
|
22
|
+
id: string;
|
|
23
|
+
entityType: 'CUSTOM_FIELD';
|
|
24
|
+
fieldType: CustomFieldType;
|
|
25
|
+
assetClass?: string;
|
|
42
26
|
};
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
*
|
|
46
|
-
* All question-specific types extend this via intersection (`&`).
|
|
47
|
-
*/
|
|
48
|
-
type QuestionBase = {
|
|
49
|
-
/**
|
|
50
|
-
* Unique identifier for this question.
|
|
51
|
-
*
|
|
52
|
-
* ⚠️ CRITICAL: Set this as the `id` attribute on the outermost DOM element
|
|
53
|
-
* so the SDK's scroll-to-error logic can find it via `document.getElementById`.
|
|
54
|
-
*/
|
|
27
|
+
/** Option-scoped entity for rank-order logic leaves. */
|
|
28
|
+
type LogicSubConditionEntity = {
|
|
55
29
|
id: string;
|
|
56
|
-
|
|
57
|
-
* Question text — may contain HTML markup.
|
|
58
|
-
* Always render with `dangerouslySetInnerHTML` or an HTML-safe renderer.
|
|
59
|
-
*/
|
|
60
|
-
text: string;
|
|
61
|
-
/**
|
|
62
|
-
* Optional description / supplementary instruction text — may contain HTML markup.
|
|
63
|
-
* Rendered below the main question text.
|
|
64
|
-
*/
|
|
65
|
-
description?: string;
|
|
66
|
-
/** Whether the respondent must answer this question before proceeding */
|
|
67
|
-
required?: boolean;
|
|
68
|
-
/** Localised error message shown when a required question is left unanswered */
|
|
69
|
-
requiredErrorMessage?: string;
|
|
70
|
-
/**
|
|
71
|
-
* Ordinal position of this question in the survey (1-indexed).
|
|
72
|
-
* Useful for displaying question numbers in the UI.
|
|
73
|
-
*/
|
|
74
|
-
questionNumber?: number;
|
|
75
|
-
/**
|
|
76
|
-
* URL of a media asset displayed alongside the question (container image/video).
|
|
77
|
-
* This field is present on ANY question type that has an attached container asset —
|
|
78
|
-
* not just TEXT_AND_MEDIA questions.
|
|
79
|
-
*/
|
|
80
|
-
containerMediaUrl?: string;
|
|
81
|
-
/**
|
|
82
|
-
* MIME type of the container asset.
|
|
83
|
-
* Use this to decide between `<img>` and `<video>` rendering.
|
|
84
|
-
*/
|
|
85
|
-
containerMediaMimeType?: string;
|
|
86
|
-
/**
|
|
87
|
-
* Layout alignment of the container media relative to the question text.
|
|
88
|
-
* Sourced from the `QUESTION_CONTAINER_MEDIA_ALIGNMENT` question config.
|
|
89
|
-
* Common values: `'LEFT_CENTER'`, `'RIGHT_CENTER'`, `'TOP'`, `'BOTTOM'`
|
|
90
|
-
*/
|
|
91
|
-
containerMediaAlignment?: string;
|
|
92
|
-
/**
|
|
93
|
-
* Width of the container media as a percentage of the question card width.
|
|
94
|
-
* Sourced from the `TEXT_AND_MEDIA_SIZE` question config.
|
|
95
|
-
* e.g. `50` means the media takes up 50% of the width.
|
|
96
|
-
*/
|
|
97
|
-
containerMediaSize?: number;
|
|
30
|
+
entityType: 'OPTION';
|
|
98
31
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
*
|
|
103
|
-
* API source: `SCALE` answerType with `SCALE_TYPE=TEN_POINT` config (or `NPS_SCALE`).
|
|
104
|
-
* Answer shape: `number` — the selected badge value (e.g. `7`).
|
|
105
|
-
*
|
|
106
|
-
* The `options` array is auto-generated (0–10) if the API omits it;
|
|
107
|
-
* each option carries a color from the NPS traffic-light palette
|
|
108
|
-
* (red for 0–6, amber for 7–8, green for 9–10).
|
|
109
|
-
*/
|
|
110
|
-
type RatingQuestion = QuestionBase & {
|
|
111
|
-
type: 'rating';
|
|
112
|
-
/** Selectable rating options (0–10), each with an NPS traffic-light color */
|
|
113
|
-
options: SurveyOption[];
|
|
114
|
-
/** Label shown at the left/low end of the scale (e.g. "Not Likely") */
|
|
115
|
-
minLabel?: string;
|
|
116
|
-
/** Label shown at the middle of the scale (e.g. "Neutral") */
|
|
117
|
-
midLabel?: string;
|
|
118
|
-
/** Label shown at the right/high end of the scale (e.g. "Extremely Likely") */
|
|
119
|
-
maxLabel?: string;
|
|
120
|
-
/**
|
|
121
|
-
* Fractional position index for the mid label within the option list.
|
|
122
|
-
* Used to compute the CSS `left` percentage offset of the mid-label element.
|
|
123
|
-
* Formula: `(midLabelIndex / (options.length - 1)) * 100`%
|
|
124
|
-
*/
|
|
125
|
-
midLabelIndex?: number;
|
|
126
|
-
/** Whether the scale options should be rendered in reverse order (high → low) */
|
|
127
|
-
reverseScaleOrder?: boolean;
|
|
128
|
-
/** Visual style for each option button */
|
|
129
|
-
buttonVariant?: 'radio' | 'numbered' | 'emoji';
|
|
32
|
+
type LogicFilterGroup = {
|
|
33
|
+
filterType: 'AND' | 'OR';
|
|
34
|
+
filters: LogicFilterNode[];
|
|
130
35
|
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
36
|
+
type LogicFilterLeaf = {
|
|
37
|
+
filterType: string;
|
|
38
|
+
field?: string;
|
|
39
|
+
values?: LogicFilterValue[];
|
|
40
|
+
details?: {
|
|
41
|
+
conditionEntity?: LogicConditionEntity;
|
|
42
|
+
subConditionEntity?: LogicSubConditionEntity;
|
|
43
|
+
valueAdditional?: {
|
|
44
|
+
timezone?: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
type LogicFilterNode = LogicFilterGroup | LogicFilterLeaf;
|
|
49
|
+
type SkipLogic = {
|
|
50
|
+
id: string;
|
|
51
|
+
skipTo: {
|
|
52
|
+
id: string;
|
|
53
|
+
entityType: 'QUESTION' | 'END_OF_SURVEY';
|
|
54
|
+
};
|
|
55
|
+
condition: LogicFilterGroup;
|
|
56
|
+
};
|
|
57
|
+
type DisplayLogic = {
|
|
58
|
+
condition: LogicFilterGroup;
|
|
59
|
+
isDynamicAppearanceEnabled: boolean;
|
|
60
|
+
};
|
|
61
|
+
/** Sub-entity logic (options, statement rows, scale columns) — mapped from API sub-entity displayLogic. */
|
|
62
|
+
type AnswerLogic = {
|
|
63
|
+
condition: LogicFilterGroup;
|
|
64
|
+
};
|
|
65
|
+
type QuestionDisplayVariant = {
|
|
66
|
+
id: string;
|
|
67
|
+
questionText: string;
|
|
68
|
+
displayLogic?: DisplayLogic;
|
|
69
|
+
};
|
|
70
|
+
type QuestionWithLogics = {
|
|
71
|
+
skipLogics?: SkipLogic[];
|
|
72
|
+
displayLogic?: DisplayLogic;
|
|
73
|
+
displayVariants?: QuestionDisplayVariant[];
|
|
147
74
|
};
|
|
148
75
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
* between a single-line `<input>` and a multi-line `<textarea>`.
|
|
158
|
-
*/
|
|
159
|
-
type TextQuestion = QuestionBase & {
|
|
160
|
-
type: 'text';
|
|
161
|
-
/** Maximum number of characters allowed; should be enforced client-side */
|
|
162
|
-
maxCharacterCount?: number;
|
|
163
|
-
/** Placeholder hint shown inside the empty input field */
|
|
164
|
-
placeholder?: string;
|
|
165
|
-
/**
|
|
166
|
-
* Text input variant.
|
|
167
|
-
* - `'short'` — Rendered as a single-line text input.
|
|
168
|
-
* - `'long'` — Rendered as a multi-line textarea.
|
|
169
|
-
*/
|
|
170
|
-
inputVariant?: 'short' | 'long';
|
|
76
|
+
type ContainerMedia = {
|
|
77
|
+
url?: string;
|
|
78
|
+
mimeType?: string;
|
|
79
|
+
alignment?: string;
|
|
80
|
+
size?: number;
|
|
81
|
+
};
|
|
82
|
+
type QuestionMedia = ContainerMedia & {
|
|
83
|
+
title?: string;
|
|
171
84
|
};
|
|
172
85
|
|
|
173
|
-
|
|
174
|
-
* A single row (sub-question) in a matrix question.
|
|
175
|
-
* Each row represents an independent statement the respondent rates
|
|
176
|
-
* by selecting one of the shared column options.
|
|
177
|
-
*/
|
|
178
|
-
type MatrixRow = {
|
|
179
|
-
/** Unique row ID — used as the key in the `Record<rowId, value>` answer map */
|
|
86
|
+
type StatementRow = {
|
|
180
87
|
id: string;
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
/** Right-side statement for bipolar scales (e.g. "Agree" ↔ "Disagree") */
|
|
184
|
-
rightText?: string;
|
|
88
|
+
statementText: string;
|
|
89
|
+
answerLogic?: AnswerLogic;
|
|
185
90
|
};
|
|
186
|
-
|
|
187
|
-
* A single column header in a matrix question.
|
|
188
|
-
* Columns are shared across all rows; selecting a cell in a column records
|
|
189
|
-
* that column's `value` for the corresponding row.
|
|
190
|
-
*/
|
|
191
|
-
type MatrixColumn = {
|
|
192
|
-
/** Unique column identifier */
|
|
91
|
+
type ScaleColumn = {
|
|
193
92
|
id: string;
|
|
194
|
-
/** Display label shown in the column header (e.g. "Strongly Agree") */
|
|
195
93
|
label: string;
|
|
196
|
-
|
|
197
|
-
value: string | number | null;
|
|
198
|
-
/** Optional color hint — used by RATING_MATRIX scale columns (HSL or hex) */
|
|
199
|
-
color?: string;
|
|
94
|
+
answerLogic?: AnswerLogic;
|
|
200
95
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
type MatrixQuestion = QuestionBase & {
|
|
215
|
-
type: 'matrix';
|
|
216
|
-
/** Original API sub-type — use this to apply the correct visual variant */
|
|
217
|
-
subType: 'CFM_MATRIX' | 'CSAT_MATRIX' | 'RATING_MATRIX';
|
|
218
|
-
/** Ordered list of row sub-questions (statements to rate) */
|
|
219
|
-
rows: MatrixRow[];
|
|
220
|
-
/**
|
|
221
|
-
* Shared column header options (same columns appear for every row).
|
|
222
|
-
* Columns with `value === null` represent the N/A column.
|
|
223
|
-
*/
|
|
224
|
-
columns: MatrixColumn[];
|
|
225
|
-
/** Visual display type for cell input controls (only applies to CSAT_MATRIX) */
|
|
226
|
-
buttonType?: SurveyButtonType;
|
|
227
|
-
/** Whether the last column is a Not Applicable (N/A) option */
|
|
228
|
-
hasNotApplicable?: boolean;
|
|
229
|
-
/** Whether the scale columns should be displayed in reverse order (high → low) */
|
|
230
|
-
reverseScaleOrder?: boolean;
|
|
231
|
-
/**
|
|
232
|
-
* Anchor labels displayed above the scale columns at evenly distributed positions.
|
|
233
|
-
* (e.g. `['Strongly Disagree', 'Neutral', 'Strongly Agree']`)
|
|
234
|
-
*/
|
|
235
|
-
labels?: string[];
|
|
236
|
-
/**
|
|
237
|
-
* Layout format for the matrix.
|
|
238
|
-
* - `'standard'` — All rows displayed as a grid at once.
|
|
239
|
-
* - `'carousel'` — One row shown at a time with prev/next navigation.
|
|
240
|
-
* - `'dropdown'` — Each row's answer is selected via a dropdown menu.
|
|
241
|
-
*/
|
|
242
|
-
matrixFormat?: 'standard' | 'carousel' | 'dropdown';
|
|
243
|
-
/**
|
|
244
|
-
* Scale polarity for CFM_MATRIX.
|
|
245
|
-
* - `'likert'` — Standard unipolar scale (e.g. Strongly Agree → Strongly Disagree).
|
|
246
|
-
* - `'bipolar'` — Two-sided scale with opposite statements at each end.
|
|
247
|
-
*/
|
|
248
|
-
matrixType?: 'likert' | 'bipolar';
|
|
249
|
-
/**
|
|
250
|
-
* Answer selection mode for CFM_MATRIX.
|
|
251
|
-
* - `'single'` — One selection per row.
|
|
252
|
-
* - `'multiple'` — Multiple selections allowed per row.
|
|
253
|
-
*/
|
|
254
|
-
answerType?: 'single' | 'multiple';
|
|
255
|
-
/** Whether to transpose the table (rows become columns and vice versa) */
|
|
256
|
-
transposeTable?: boolean;
|
|
257
|
-
/** Whether to repeat the column header row at regular intervals */
|
|
258
|
-
repeatScale?: boolean;
|
|
259
|
-
/** Whether to show the scale header row at all */
|
|
260
|
-
enableScale?: boolean;
|
|
96
|
+
|
|
97
|
+
declare const QUESTION_TYPE: {
|
|
98
|
+
readonly MCQ: "MCQ";
|
|
99
|
+
readonly TEXTFIELD: "TEXTFIELD";
|
|
100
|
+
readonly NPS_SCALE: "NPS_SCALE";
|
|
101
|
+
readonly CFM_MATRIX: "CFM_MATRIX";
|
|
102
|
+
readonly CSAT_MATRIX: "CSAT_MATRIX";
|
|
103
|
+
readonly RATING_MATRIX: "RATING_MATRIX";
|
|
104
|
+
readonly SLIDER_MATRIX: "SLIDER_MATRIX";
|
|
105
|
+
readonly FILE_UPLOAD: "FILE_UPLOAD";
|
|
106
|
+
readonly TEXT_AND_MEDIA: "TEXT_AND_MEDIA";
|
|
107
|
+
readonly HEATMAP: "HEATMAP";
|
|
108
|
+
readonly RANK_ORDER: "RANK_ORDER";
|
|
261
109
|
};
|
|
110
|
+
type QuestionType = (typeof QUESTION_TYPE)[keyof typeof QUESTION_TYPE];
|
|
262
111
|
|
|
263
|
-
/**
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
112
|
+
/** Multiple-choice question (API: MCQ). */
|
|
113
|
+
type McqQuestion = {
|
|
114
|
+
type: typeof QUESTION_TYPE.MCQ;
|
|
115
|
+
id: string;
|
|
116
|
+
questionText: string;
|
|
117
|
+
questionDescription?: string;
|
|
118
|
+
questionHint?: string;
|
|
119
|
+
required: boolean;
|
|
120
|
+
requiredErrorMessage?: string;
|
|
121
|
+
questionNumber?: number;
|
|
122
|
+
containerMedia?: ContainerMedia;
|
|
123
|
+
referencedQuestionIds?: string[];
|
|
124
|
+
options: McqOption[];
|
|
125
|
+
selectionMode: 'single' | 'multiple';
|
|
126
|
+
displayFormat: 'list' | 'grid';
|
|
127
|
+
shuffleOptions: boolean;
|
|
128
|
+
columnCount?: number;
|
|
129
|
+
defaultOptionIds?: string[];
|
|
130
|
+
minSelections?: number;
|
|
131
|
+
maxSelections?: number;
|
|
132
|
+
answerConditionErrorMessage?: string;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
type McqOption = {
|
|
136
|
+
id: string;
|
|
137
|
+
optionLabel: string;
|
|
138
|
+
answerLogic?: AnswerLogic;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/** NPS 0–10 scale question (API: NPS_SCALE). */
|
|
142
|
+
type NpsQuestion = {
|
|
143
|
+
type: typeof QUESTION_TYPE.NPS_SCALE;
|
|
144
|
+
id: string;
|
|
145
|
+
questionText: string;
|
|
146
|
+
questionDescription?: string;
|
|
147
|
+
questionHint?: string;
|
|
148
|
+
required: boolean;
|
|
149
|
+
requiredErrorMessage?: string;
|
|
150
|
+
questionNumber?: number;
|
|
151
|
+
containerMedia?: ContainerMedia;
|
|
152
|
+
referencedQuestionIds?: string[];
|
|
153
|
+
options: NpsScalePoint[];
|
|
282
154
|
minLabel?: string;
|
|
283
|
-
|
|
155
|
+
midLabel?: string;
|
|
284
156
|
maxLabel?: string;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
hasNotApplicable?: boolean;
|
|
289
|
-
/** Whether the scale columns should be displayed in reverse order (high → low) */
|
|
290
|
-
reverseScaleOrder?: boolean;
|
|
291
|
-
/**
|
|
292
|
-
* Anchor labels displayed above the scale columns at evenly distributed positions.
|
|
293
|
-
* (e.g. `['Strongly Disagree', 'Neutral', 'Strongly Agree']`)
|
|
294
|
-
*/
|
|
295
|
-
labels?: string[];
|
|
157
|
+
midLabelIndex?: number;
|
|
158
|
+
reverseScaleOrder: boolean;
|
|
159
|
+
buttonStyle: 'standard' | 'numbered' | 'emoji';
|
|
296
160
|
};
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
* Each row carries its own independent slider range configuration.
|
|
301
|
-
*/
|
|
302
|
-
type SliderMatrixRow = MatrixRow & {
|
|
303
|
-
/** Minimum value of this row's slider track */
|
|
304
|
-
min: number;
|
|
305
|
-
/** Maximum value of this row's slider track */
|
|
306
|
-
max: number;
|
|
307
|
-
/** Step increment between selectable values (e.g. `1` for integers) */
|
|
308
|
-
step: number;
|
|
309
|
-
/** Optional initial position of the slider handle before interaction */
|
|
310
|
-
defaultValue?: number;
|
|
161
|
+
type NpsScalePoint = {
|
|
162
|
+
id: string;
|
|
163
|
+
optionLabel: string;
|
|
311
164
|
};
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
165
|
+
|
|
166
|
+
/** CSAT matrix grid (API: CSAT_MATRIX only). */
|
|
167
|
+
type CsatQuestion = {
|
|
168
|
+
type: typeof QUESTION_TYPE.CSAT_MATRIX;
|
|
169
|
+
id: string;
|
|
170
|
+
questionText: string;
|
|
171
|
+
questionDescription?: string;
|
|
172
|
+
questionHint?: string;
|
|
173
|
+
required: boolean;
|
|
174
|
+
requiredErrorMessage?: string;
|
|
175
|
+
questionNumber?: number;
|
|
176
|
+
containerMedia?: ContainerMedia;
|
|
177
|
+
referencedQuestionIds?: string[];
|
|
178
|
+
statementRows: CsatStatementRow[];
|
|
179
|
+
scaleColumns: CsatScaleColumn[];
|
|
180
|
+
scaleAnchorLabels?: string[];
|
|
181
|
+
displayStyle: 'emoji' | 'star' | 'standard' | 'numbered' | 'dropdown' | 'selectbox' | 'graphics';
|
|
182
|
+
hasNotApplicableOption: boolean;
|
|
183
|
+
reverseScaleOrder: boolean;
|
|
184
|
+
gridLayout: 'standard' | 'carousel' | 'dropdown';
|
|
323
185
|
};
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
* Number of discrete tick marks rendered on the slider track.
|
|
343
|
-
* Defaults to `10` if not set by the survey configuration.
|
|
344
|
-
*/
|
|
345
|
-
ticks?: number;
|
|
346
|
-
/**
|
|
347
|
-
* Pre-calculated tick values with display labels and HSL color mapping.
|
|
348
|
-
* The colors transition Red → Amber → Green from index 0 to the last tick.
|
|
349
|
-
*/
|
|
350
|
-
tickValues?: TickValue[];
|
|
351
|
-
/** Whether to show a numeric text input box alongside the slider handle */
|
|
352
|
-
enableInputBox?: boolean;
|
|
353
|
-
/** Whether to display the current value as a tooltip on the slider thumb */
|
|
354
|
-
displayValues?: boolean;
|
|
355
|
-
/** Whether to include a Not Applicable (N/A) option per row */
|
|
356
|
-
enableNotApplicable?: boolean;
|
|
357
|
-
/**
|
|
358
|
-
* Whether this is a Graphics Slider (renders an emoji thumb instead of a plain handle).
|
|
359
|
-
* When `'graphics'`, the slider thumb shows a sentiment emoji that changes with the value.
|
|
360
|
-
*/
|
|
361
|
-
sliderType?: 'graphics';
|
|
186
|
+
type CsatStatementRow = StatementRow;
|
|
187
|
+
type CsatScaleColumn = ScaleColumn;
|
|
188
|
+
|
|
189
|
+
/** Free-text input (API: TEXTFIELD). */
|
|
190
|
+
type TextInputQuestion = {
|
|
191
|
+
type: typeof QUESTION_TYPE.TEXTFIELD;
|
|
192
|
+
id: string;
|
|
193
|
+
questionText: string;
|
|
194
|
+
questionDescription?: string;
|
|
195
|
+
questionHint?: string;
|
|
196
|
+
required: boolean;
|
|
197
|
+
requiredErrorMessage?: string;
|
|
198
|
+
questionNumber?: number;
|
|
199
|
+
containerMedia?: ContainerMedia;
|
|
200
|
+
referencedQuestionIds?: string[];
|
|
201
|
+
placeholder?: string;
|
|
202
|
+
maxCharacterCount?: number;
|
|
203
|
+
inputVariant: 'short' | 'long';
|
|
362
204
|
};
|
|
363
205
|
|
|
364
|
-
/**
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
* Use this to decide between `<img>` and `<video>` rendering.
|
|
387
|
-
*/
|
|
388
|
-
mediaMimeType?: 'image/*' | 'video/*' | string;
|
|
389
|
-
/** Optional caption or alt text rendered beneath the media asset */
|
|
390
|
-
mediaTitle?: string;
|
|
391
|
-
/**
|
|
392
|
-
* Layout position of the media relative to the text content.
|
|
393
|
-
* Sourced from the `TEXT_AND_MEDIA_ALIGNMENT` question config.
|
|
394
|
-
* (e.g. `'BOTTOM_LEFT'`, `'TOP_CENTER'`, `'LEFT_CENTER'`)
|
|
395
|
-
*/
|
|
396
|
-
mediaAlignment?: string;
|
|
397
|
-
/**
|
|
398
|
-
* Width of the media container as a percentage of the card width.
|
|
399
|
-
* Sourced from the `TEXT_AND_MEDIA_SIZE` question config.
|
|
400
|
-
* (e.g. `50` means the image takes up 50% of the width)
|
|
401
|
-
*/
|
|
402
|
-
mediaSize?: number;
|
|
206
|
+
/** CFM matrix grid (API: CFM_MATRIX). */
|
|
207
|
+
type CfmMatrixQuestion = {
|
|
208
|
+
type: typeof QUESTION_TYPE.CFM_MATRIX;
|
|
209
|
+
id: string;
|
|
210
|
+
questionText: string;
|
|
211
|
+
questionDescription?: string;
|
|
212
|
+
questionHint?: string;
|
|
213
|
+
required: boolean;
|
|
214
|
+
requiredErrorMessage?: string;
|
|
215
|
+
questionNumber?: number;
|
|
216
|
+
containerMedia?: ContainerMedia;
|
|
217
|
+
referencedQuestionIds?: string[];
|
|
218
|
+
statementRows: CfmMatrixStatementRow[];
|
|
219
|
+
scaleColumns: CfmMatrixScaleColumn[];
|
|
220
|
+
statementLayout: 'likert' | 'bipolar';
|
|
221
|
+
selectionMode: 'single' | 'multiple';
|
|
222
|
+
gridLayout: 'standard' | 'carousel' | 'dropdown';
|
|
223
|
+
transposeTable: boolean;
|
|
224
|
+
repeatColumnHeaders: boolean;
|
|
225
|
+
hasNotApplicableOption: boolean;
|
|
226
|
+
showColumnHeaders: boolean;
|
|
227
|
+
scaleAnchorLabels?: string[];
|
|
403
228
|
};
|
|
229
|
+
type CfmMatrixStatementRow = StatementRow & {
|
|
230
|
+
oppositeStatementText?: string;
|
|
231
|
+
};
|
|
232
|
+
type CfmMatrixScaleColumn = ScaleColumn;
|
|
404
233
|
|
|
405
|
-
/**
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
options: SurveyOption[];
|
|
421
|
-
/** Label for the lowest satisfaction level (e.g. "Very Dissatisfied") */
|
|
234
|
+
/** NPS-style rating matrix grid (API: RATING_MATRIX). */
|
|
235
|
+
type RatingMatrixQuestion = {
|
|
236
|
+
type: typeof QUESTION_TYPE.RATING_MATRIX;
|
|
237
|
+
id: string;
|
|
238
|
+
questionText: string;
|
|
239
|
+
questionDescription?: string;
|
|
240
|
+
questionHint?: string;
|
|
241
|
+
required: boolean;
|
|
242
|
+
requiredErrorMessage?: string;
|
|
243
|
+
questionNumber?: number;
|
|
244
|
+
containerMedia?: ContainerMedia;
|
|
245
|
+
referencedQuestionIds?: string[];
|
|
246
|
+
statementRows: RatingMatrixStatementRow[];
|
|
247
|
+
scaleColumns: RatingMatrixScaleColumn[];
|
|
248
|
+
scaleAnchorLabels?: string[];
|
|
422
249
|
minLabel?: string;
|
|
423
|
-
/** Label for the highest satisfaction level (e.g. "Very Satisfied") */
|
|
424
250
|
maxLabel?: string;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
/** Whether the options should be displayed in reverse order (high → low) */
|
|
430
|
-
reverseScaleOrder?: boolean;
|
|
431
|
-
/**
|
|
432
|
-
* Where the min/max labels are positioned relative to the scale buttons.
|
|
433
|
-
* - `'top'` — Labels appear above the scale
|
|
434
|
-
* - `'bottom'` — Labels appear below the scale
|
|
435
|
-
* - `'hidden'` — Labels are not shown
|
|
436
|
-
*/
|
|
437
|
-
labelPosition?: 'top' | 'bottom' | 'hidden';
|
|
251
|
+
displayStyle: 'emoji' | 'star' | 'standard' | 'numbered' | 'dropdown' | 'selectbox' | 'graphics';
|
|
252
|
+
hasNotApplicableOption: boolean;
|
|
253
|
+
reverseScaleOrder: boolean;
|
|
254
|
+
gridLayout: 'standard' | 'carousel' | 'dropdown';
|
|
438
255
|
};
|
|
256
|
+
type RatingMatrixStatementRow = StatementRow;
|
|
257
|
+
type RatingMatrixScaleColumn = ScaleColumn;
|
|
439
258
|
|
|
440
|
-
/**
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
259
|
+
/** Slider matrix grid — one slider per row (API: SLIDER_MATRIX). */
|
|
260
|
+
type SliderMatrixQuestion = {
|
|
261
|
+
type: typeof QUESTION_TYPE.SLIDER_MATRIX;
|
|
262
|
+
id: string;
|
|
263
|
+
questionText: string;
|
|
264
|
+
questionDescription?: string;
|
|
265
|
+
questionHint?: string;
|
|
266
|
+
required: boolean;
|
|
267
|
+
requiredErrorMessage?: string;
|
|
268
|
+
questionNumber?: number;
|
|
269
|
+
containerMedia?: ContainerMedia;
|
|
270
|
+
referencedQuestionIds?: string[];
|
|
271
|
+
statementRows: SliderMatrixStatementRow[];
|
|
272
|
+
scaleAnchorLabels?: string[];
|
|
273
|
+
ticks: {
|
|
274
|
+
count: number;
|
|
275
|
+
marks: SliderMatrixTickMark[];
|
|
276
|
+
};
|
|
277
|
+
enableInputBox: boolean;
|
|
278
|
+
displayValues?: boolean;
|
|
279
|
+
hasNotApplicableOption: boolean;
|
|
280
|
+
sliderStyle?: 'standard' | 'graphics';
|
|
281
|
+
};
|
|
282
|
+
type SliderMatrixStatementRow = StatementRow & {
|
|
450
283
|
min: number;
|
|
451
|
-
/** Maximum value at the right end of the slider track */
|
|
452
284
|
max: number;
|
|
453
|
-
/** Step increment between selectable positions (e.g. `1` for whole numbers) */
|
|
454
285
|
step: number;
|
|
455
|
-
/** Optional initial position of the slider handle before interaction */
|
|
456
286
|
defaultValue?: number;
|
|
457
|
-
/** Label displayed at the minimum (left) end of the track */
|
|
458
|
-
minLabel?: string;
|
|
459
|
-
/** Label displayed at the maximum (right) end of the track */
|
|
460
|
-
maxLabel?: string;
|
|
461
|
-
/** Whether to show a numeric text input box alongside the slider handle */
|
|
462
|
-
enableInputBox?: boolean;
|
|
463
|
-
/** Whether to display the current value as a floating tooltip on the thumb */
|
|
464
|
-
displayValues?: boolean;
|
|
465
287
|
};
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
*
|
|
470
|
-
* Unlike the NPS `'rating'` type, this does NOT apply traffic-light colors to options
|
|
471
|
-
* and is visually rendered as stars, emojis, thumbs, or similar icons.
|
|
472
|
-
*
|
|
473
|
-
* API source: `SCALE` answerType with `SCALE_TYPE=STAR`, `SCALE_TYPE=EMOJI`,
|
|
474
|
-
* or `SCALE_TYPE=FIVE_POINT` config.
|
|
475
|
-
* Answer shape: `number` — the selected star/icon value.
|
|
476
|
-
*/
|
|
477
|
-
type RatingScaleQuestion = QuestionBase & {
|
|
478
|
-
type: 'rating_scale';
|
|
479
|
-
/**
|
|
480
|
-
* Selectable rating options (typically 1–5 or 1–10).
|
|
481
|
-
* These carry no NPS colors — the UI should render them as stars or custom icons.
|
|
482
|
-
*/
|
|
483
|
-
options: SurveyOption[];
|
|
484
|
-
/** Label for the lowest rating end (e.g. "Poor") */
|
|
485
|
-
minLabel?: string;
|
|
486
|
-
/** Label for the midpoint of the scale (e.g. "Average") */
|
|
487
|
-
midLabel?: string;
|
|
488
|
-
/** Label for the highest rating end (e.g. "Excellent") */
|
|
489
|
-
maxLabel?: string;
|
|
490
|
-
/**
|
|
491
|
-
* Fractional position index for the mid label within the option list.
|
|
492
|
-
* Used to compute the CSS `left` percentage offset of the mid-label element.
|
|
493
|
-
* Formula: `(midLabelIndex / (options.length - 1)) * 100`%
|
|
494
|
-
*/
|
|
495
|
-
midLabelIndex?: number;
|
|
496
|
-
/** Whether the scale options should be displayed in reverse order (high → low) */
|
|
497
|
-
reverseScaleOrder?: boolean;
|
|
498
|
-
/**
|
|
499
|
-
* The specific icon style used for this scale.
|
|
500
|
-
* - `'star'` — Classic star icons
|
|
501
|
-
* - `'emoji'` — Sentiment emoji faces
|
|
502
|
-
*/
|
|
503
|
-
scaleStyle?: 'star' | 'emoji';
|
|
288
|
+
type SliderMatrixTickMark = {
|
|
289
|
+
tickPosition: number;
|
|
290
|
+
tickLabel: string;
|
|
504
291
|
};
|
|
505
292
|
|
|
506
|
-
/**
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
293
|
+
/** File attachment question (API: FILE_UPLOAD). */
|
|
294
|
+
type FileUploadQuestion = {
|
|
295
|
+
type: typeof QUESTION_TYPE.FILE_UPLOAD;
|
|
296
|
+
id: string;
|
|
297
|
+
questionText: string;
|
|
298
|
+
questionDescription?: string;
|
|
299
|
+
questionHint?: string;
|
|
300
|
+
required: boolean;
|
|
301
|
+
requiredErrorMessage?: string;
|
|
302
|
+
questionNumber?: number;
|
|
303
|
+
containerMedia?: ContainerMedia;
|
|
304
|
+
referencedQuestionIds?: string[];
|
|
305
|
+
uploadMessage?: string;
|
|
306
|
+
supportedFileFormats: string[];
|
|
307
|
+
maxFileCount?: number;
|
|
308
|
+
fileSizeLimit?: number;
|
|
309
|
+
fileSizeLimitType: 'PER_FILE' | 'IN_TOTAL';
|
|
310
|
+
};
|
|
519
311
|
type UploadedFile = {
|
|
520
|
-
/** Unique asset ID returned by the upload server */
|
|
521
312
|
id: string;
|
|
522
|
-
/** Original filename of the uploaded file */
|
|
523
313
|
name: string;
|
|
524
|
-
/** Public URL to access the uploaded file */
|
|
525
314
|
mediaUrl: string;
|
|
526
|
-
/** MIME type of the uploaded file (e.g. `'image/png'`, `'application/pdf'`) */
|
|
527
315
|
mimeType?: string;
|
|
528
|
-
/** File size in bytes */
|
|
529
316
|
size?: number;
|
|
530
317
|
};
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
uploadMessage?: string;
|
|
545
|
-
/**
|
|
546
|
-
* List of accepted file extensions in uppercase without dots (e.g. `['PDF', 'PNG', 'DOCX']`).
|
|
547
|
-
* Use these to set the `accept` attribute on the `<input type="file">` element.
|
|
548
|
-
*/
|
|
549
|
-
supportedFileFormats?: string[];
|
|
550
|
-
/**
|
|
551
|
-
* Maximum number of files the respondent can attach to this question.
|
|
552
|
-
* If `undefined`, no limit is enforced by the SDK.
|
|
553
|
-
*/
|
|
554
|
-
maxFileCount?: number;
|
|
555
|
-
/**
|
|
556
|
-
* Maximum file size in megabytes (MB).
|
|
557
|
-
* Applies either per-file or in total, depending on `fileSizeLimitType`.
|
|
558
|
-
*/
|
|
559
|
-
fileSizeLimit?: number;
|
|
560
|
-
/**
|
|
561
|
-
* Determines how `fileSizeLimit` is applied.
|
|
562
|
-
* - `'PER_FILE'` — Each individual file must not exceed `fileSizeLimit` MB.
|
|
563
|
-
* - `'IN_TOTAL'` — The combined size of all uploads must not exceed `fileSizeLimit` MB.
|
|
564
|
-
*/
|
|
565
|
-
fileSizeLimitType?: 'PER_FILE' | 'IN_TOTAL';
|
|
318
|
+
|
|
319
|
+
/** Display-only text and media card (API: TEXT_AND_MEDIA). No answer recorded. */
|
|
320
|
+
type TextAndMediaQuestion = {
|
|
321
|
+
type: typeof QUESTION_TYPE.TEXT_AND_MEDIA;
|
|
322
|
+
id: string;
|
|
323
|
+
questionText: string;
|
|
324
|
+
questionDescription?: string;
|
|
325
|
+
questionHint?: string;
|
|
326
|
+
required: boolean;
|
|
327
|
+
requiredErrorMessage?: string;
|
|
328
|
+
questionNumber?: number;
|
|
329
|
+
referencedQuestionIds?: string[];
|
|
330
|
+
media?: QuestionMedia;
|
|
566
331
|
};
|
|
567
332
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
333
|
+
type HeatmapRegion = {
|
|
334
|
+
id: string;
|
|
335
|
+
label: string;
|
|
336
|
+
x: number;
|
|
337
|
+
y: number;
|
|
338
|
+
width: number;
|
|
339
|
+
height: number;
|
|
340
|
+
color?: string;
|
|
341
|
+
};
|
|
342
|
+
/** Image click-map question (API: HEATMAP). */
|
|
343
|
+
type HeatmapQuestion = {
|
|
344
|
+
type: typeof QUESTION_TYPE.HEATMAP;
|
|
345
|
+
id: string;
|
|
346
|
+
questionText: string;
|
|
347
|
+
questionDescription?: string;
|
|
348
|
+
questionHint?: string;
|
|
349
|
+
required: boolean;
|
|
350
|
+
requiredErrorMessage?: string;
|
|
351
|
+
questionNumber?: number;
|
|
352
|
+
imageUrl: string;
|
|
353
|
+
regions: HeatmapRegion[];
|
|
354
|
+
maxClicksAllowed: number;
|
|
355
|
+
referenceWidth: number;
|
|
356
|
+
referenceHeight: number;
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
type RankOrderInteractionMode = 'dropdown' | 'dragAndDrop';
|
|
360
|
+
type RankOrderOptionDisplay = 'textOnly' | 'imageOnly' | 'textAndImage';
|
|
361
|
+
type RankOrderOption = {
|
|
362
|
+
id: string;
|
|
363
|
+
optionLabel: string;
|
|
364
|
+
imageUrl?: string;
|
|
365
|
+
previewImageUrl?: string;
|
|
366
|
+
answerLogic?: AnswerLogic;
|
|
367
|
+
};
|
|
368
|
+
/** Rank-order question (API: RANK_ORDER). */
|
|
369
|
+
type RankOrderQuestion = {
|
|
370
|
+
type: typeof QUESTION_TYPE.RANK_ORDER;
|
|
371
|
+
id: string;
|
|
372
|
+
questionText: string;
|
|
373
|
+
questionDescription?: string;
|
|
374
|
+
questionHint?: string;
|
|
375
|
+
required: boolean;
|
|
376
|
+
requiredErrorMessage?: string;
|
|
377
|
+
questionNumber?: number;
|
|
378
|
+
containerMedia?: ContainerMedia;
|
|
379
|
+
referencedQuestionIds?: string[];
|
|
380
|
+
options: RankOrderOption[];
|
|
381
|
+
interactionMode: RankOrderInteractionMode;
|
|
382
|
+
optionDisplay: RankOrderOptionDisplay;
|
|
383
|
+
requireRankAll: boolean;
|
|
384
|
+
shuffleOptions: boolean;
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
type SpecialPage = {
|
|
388
|
+
id: string;
|
|
389
|
+
header: string;
|
|
390
|
+
title?: string;
|
|
391
|
+
description?: string;
|
|
392
|
+
ctaLabel?: string;
|
|
393
|
+
disabled?: boolean;
|
|
394
|
+
displayLogic?: DisplayLogic;
|
|
395
|
+
};
|
|
396
|
+
type SurveyPhase = {
|
|
397
|
+
kind: 'intro';
|
|
398
|
+
} | {
|
|
399
|
+
kind: 'content';
|
|
400
|
+
pageIndex: number;
|
|
401
|
+
} | {
|
|
402
|
+
kind: 'end';
|
|
403
|
+
endPageId: string;
|
|
404
|
+
} | {
|
|
405
|
+
kind: 'paused';
|
|
406
|
+
} | {
|
|
407
|
+
kind: 'submitted';
|
|
408
|
+
} | {
|
|
409
|
+
kind: 'expired';
|
|
410
|
+
} | {
|
|
411
|
+
kind: 'quota_fulfilled';
|
|
412
|
+
};
|
|
413
|
+
type SurveyPhaseFlags = {
|
|
414
|
+
expired: boolean;
|
|
415
|
+
alreadyFilled: boolean;
|
|
416
|
+
quotaFulfilled: boolean;
|
|
417
|
+
paused: boolean;
|
|
418
|
+
};
|
|
419
|
+
type SurveyQuestion = (McqQuestion & QuestionWithLogics) | (NpsQuestion & QuestionWithLogics) | (CsatQuestion & QuestionWithLogics) | (TextInputQuestion & QuestionWithLogics) | (CfmMatrixQuestion & QuestionWithLogics) | (RatingMatrixQuestion & QuestionWithLogics) | (SliderMatrixQuestion & QuestionWithLogics) | (FileUploadQuestion & QuestionWithLogics) | (TextAndMediaQuestion & QuestionWithLogics) | (HeatmapQuestion & QuestionWithLogics) | (RankOrderQuestion & QuestionWithLogics);
|
|
420
|
+
type SurveyPage = {
|
|
577
421
|
id: string;
|
|
578
|
-
/** Optional page title displayed as a section header */
|
|
579
422
|
title?: string;
|
|
580
|
-
/** Ordered list of questions on this page */
|
|
581
423
|
questions: SurveyQuestion[];
|
|
582
424
|
};
|
|
583
|
-
/**
|
|
584
|
-
* A language option available for this survey.
|
|
585
|
-
*/
|
|
586
425
|
type SurveyLanguage = {
|
|
587
|
-
/** BCP-47 language code (e.g. `'en'`, `'de'`, `'fr'`) */
|
|
588
426
|
code: string;
|
|
589
|
-
/** Human-readable language name (e.g. `'English'`, `'Deutsch'`) */
|
|
590
427
|
name: string;
|
|
591
428
|
};
|
|
592
|
-
/**
|
|
593
|
-
* The fully parsed and normalised survey structure returned by the SDK.
|
|
594
|
-
*/
|
|
595
429
|
type Survey = {
|
|
596
|
-
/** Unique survey identifier */
|
|
597
430
|
id: string;
|
|
598
|
-
/** Active language code for this response session */
|
|
599
431
|
language: string;
|
|
600
|
-
/** All languages configured for this survey */
|
|
601
432
|
languages: SurveyLanguage[];
|
|
602
|
-
|
|
603
|
-
|
|
433
|
+
pages: SurveyPage[];
|
|
434
|
+
introPage?: SpecialPage;
|
|
435
|
+
endPages: SpecialPage[];
|
|
436
|
+
pausedPage?: SpecialPage;
|
|
437
|
+
phaseFlags: SurveyPhaseFlags;
|
|
604
438
|
};
|
|
605
439
|
|
|
606
440
|
/**
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
* For multi-select grids, the value can be an array of selected column values.
|
|
610
|
-
*/
|
|
611
|
-
type MatrixAnswerMap = Record<string, string | number | null | Array<string | number | null>>;
|
|
612
|
-
/**
|
|
613
|
-
* Union of all possible answer value types across all question variants.
|
|
614
|
-
* - `string | number | null` — standard single-value questions (rating, radio, text, csat N/A)
|
|
615
|
-
* - `MatrixAnswerMap` — grid questions (matrix, rating_matrix, slider_matrix)
|
|
441
|
+
* Row-level answers for matrix question types.
|
|
442
|
+
* Scale-matrix rows store selected column IDs (strings); slider-matrix rows store numbers.
|
|
616
443
|
*/
|
|
617
|
-
type
|
|
444
|
+
type MatrixRowAnswers = Record<string, string | number | null | Array<string | number | null>>;
|
|
445
|
+
type HeatmapClickPoint = {
|
|
446
|
+
id: string;
|
|
447
|
+
x: number;
|
|
448
|
+
y: number;
|
|
449
|
+
};
|
|
450
|
+
type HeatmapAnswer = HeatmapClickPoint[];
|
|
451
|
+
/** optionId → 1-based rank. Partial map allowed when requireRankAll is false. */
|
|
452
|
+
type RankOrderAnswers = Record<string, number>;
|
|
618
453
|
/**
|
|
619
|
-
*
|
|
454
|
+
* Union of all possible answer values across question variants.
|
|
620
455
|
*/
|
|
456
|
+
type AnswerValue = string | string[] | number | null | MatrixRowAnswers | RankOrderAnswers | UploadedFileAnswer[] | HeatmapAnswer;
|
|
457
|
+
type UploadedFileAnswer = {
|
|
458
|
+
id: string;
|
|
459
|
+
name: string;
|
|
460
|
+
mediaUrl: string;
|
|
461
|
+
mimeType?: string;
|
|
462
|
+
size?: number;
|
|
463
|
+
};
|
|
464
|
+
/** Key-value mapping of question IDs to their answer values (client-selected ids or numbers). */
|
|
465
|
+
type SurveyAnswers = Record<string, AnswerValue>;
|
|
621
466
|
type SubmitResult = {
|
|
622
467
|
success: boolean;
|
|
623
468
|
responseId: string;
|
|
624
469
|
};
|
|
625
470
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
471
|
+
type SavePartialResponseOption = boolean | {
|
|
472
|
+
debounceMs?: number;
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
/** A single client-supplied custom field value. */
|
|
476
|
+
type CustomFieldValue = string | number | string[];
|
|
477
|
+
/** Client-supplied values keyed by custom field id (e.g. `_c_6a436c1244764c9d4a6ce2fc`). */
|
|
478
|
+
type CustomFieldValueMap = Record<string, CustomFieldValue>;
|
|
479
|
+
|
|
629
480
|
type SurveyAction = {
|
|
630
481
|
type: ACTIONS.NEXT | 'NEXT';
|
|
631
482
|
} | {
|
|
632
483
|
type: ACTIONS.PREVIOUS | 'PREVIOUS';
|
|
633
484
|
} | {
|
|
634
485
|
type: ACTIONS.SUBMIT | 'SUBMIT';
|
|
486
|
+
} | {
|
|
487
|
+
type: ACTIONS.START | 'START';
|
|
488
|
+
} | {
|
|
489
|
+
type: ACTIONS.SCROLL | 'SCROLL';
|
|
635
490
|
} | {
|
|
636
491
|
type: ACTIONS.CHANGE | 'CHANGE';
|
|
637
492
|
payload: {
|
|
638
493
|
questionId: string;
|
|
639
|
-
|
|
494
|
+
answerValue: AnswerValue;
|
|
495
|
+
};
|
|
496
|
+
} | {
|
|
497
|
+
type: ACTIONS.RECORD_QUESTION_VIEW | 'RECORD_QUESTION_VIEW';
|
|
498
|
+
payload: {
|
|
499
|
+
questionIds: string[];
|
|
640
500
|
};
|
|
641
501
|
};
|
|
642
|
-
/**
|
|
643
|
-
* Configuration settings for useSurveySDK hook behavior and layout parameters.
|
|
644
|
-
*/
|
|
645
502
|
type UseSurveySDKProps = {
|
|
646
503
|
options?: {
|
|
647
504
|
instanceId?: string;
|
|
648
505
|
language?: string;
|
|
649
506
|
placeholders?: Record<string, string>;
|
|
507
|
+
customFieldValues?: CustomFieldValueMap;
|
|
650
508
|
debug?: boolean;
|
|
509
|
+
savePartialResponse?: SavePartialResponseOption;
|
|
651
510
|
};
|
|
652
511
|
};
|
|
653
|
-
/** Return shape of the useSurveySDK hook — the agent integration contract. */
|
|
654
512
|
type UseSurveySDKReturn = {
|
|
655
513
|
surveyQueryResults: {
|
|
656
514
|
data: Survey | null;
|
|
@@ -662,43 +520,70 @@ type UseSurveySDKReturn = {
|
|
|
662
520
|
error: Error | null;
|
|
663
521
|
isLoading: boolean;
|
|
664
522
|
};
|
|
523
|
+
partialSaveResults: {
|
|
524
|
+
data: SubmitResult | null;
|
|
525
|
+
error: Error | null;
|
|
526
|
+
isLoading: boolean;
|
|
527
|
+
};
|
|
665
528
|
state: {
|
|
529
|
+
phase: SurveyPhase;
|
|
666
530
|
currentPageIndex: number;
|
|
667
531
|
currentQuestions: SurveyQuestion[];
|
|
668
|
-
|
|
532
|
+
answers: Record<string, AnswerValue>;
|
|
669
533
|
validationErrors: Record<string, string>;
|
|
670
534
|
progressPercentage: number;
|
|
535
|
+
totalQuestionsCount: number;
|
|
536
|
+
answeredQuestionsCount: number;
|
|
537
|
+
canGoBack: boolean;
|
|
538
|
+
primaryButtonType: 'next' | 'submit';
|
|
539
|
+
specialPage?: SpecialPage;
|
|
671
540
|
};
|
|
672
541
|
onAction: (action: SurveyAction) => void;
|
|
673
542
|
};
|
|
674
543
|
|
|
675
544
|
/**
|
|
676
545
|
* The main entry-point custom React hook for the survey SDK.
|
|
677
|
-
* Handles fetching survey configurations, active session state, validation,
|
|
678
|
-
* page pagination, response submission, and user progress tracking.
|
|
679
|
-
*
|
|
680
|
-
* @param props Configuration settings for hook behavior and layout parameters.
|
|
681
|
-
* @returns Unified state structures, submission indicators, and action triggers.
|
|
682
546
|
*/
|
|
683
547
|
declare function useSurveySDK({ options }?: UseSurveySDKProps): UseSurveySDKReturn;
|
|
684
548
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
* Each entry is a pre-built React element with colour and sizing.
|
|
688
|
-
*/
|
|
689
|
-
declare const CsatEmojiSet: Record<number, React.ReactNode>;
|
|
690
|
-
/**
|
|
691
|
-
* Maps a 0-based column index within a scale of `total` items
|
|
692
|
-
* to the correct professional face icon from the 11-level set.
|
|
693
|
-
*
|
|
694
|
-
* Works for any scale length. Uses specific curated subsets for 3-6 lengths.
|
|
695
|
-
*/
|
|
696
|
-
declare function getEmojiForIndex(index: number, total: number): React.ReactNode;
|
|
697
|
-
/** Legacy 1–5 mapping kept for backward compatibility with CsatScale (standalone) */
|
|
698
|
-
declare const CsatEmojiMapping: Record<number, React.ReactNode>;
|
|
699
|
-
declare const CsatStarIcons: {
|
|
700
|
-
filled: React.ReactNode;
|
|
701
|
-
empty: React.ReactNode;
|
|
549
|
+
declare const QUESTION_ACTIVITY_STATE: {
|
|
550
|
+
readonly VIEWED: "VIEWED";
|
|
702
551
|
};
|
|
703
552
|
|
|
704
|
-
|
|
553
|
+
declare function formatAnswerForDisplay(question: SurveyQuestion, answerValue: AnswerValue | undefined): string;
|
|
554
|
+
declare function resolveSurveyQuestionPlaceholders(html: string, answers: SurveyAnswers, questionsById: Map<string, SurveyQuestion>): string;
|
|
555
|
+
|
|
556
|
+
type LogicContext = {
|
|
557
|
+
answers: SurveyAnswers;
|
|
558
|
+
questionsById: ReadonlyMap<string, SurveyQuestion>;
|
|
559
|
+
customFieldValues?: Readonly<CustomFieldValueMap>;
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
declare function getVisibleStatementRows(question: SurveyQuestion, context: LogicContext): StatementRow[];
|
|
563
|
+
declare function getVisibleMcqOptions(question: SurveyQuestion, context: LogicContext): McqOption[];
|
|
564
|
+
declare function getVisibleRankOrderOptions(question: SurveyQuestion, context: LogicContext): RankOrderOption[];
|
|
565
|
+
declare function getVisibleScaleColumns(question: SurveyQuestion, context: LogicContext): ScaleColumn[];
|
|
566
|
+
|
|
567
|
+
declare function getVisibleStatementRowsForAnswers(question: SurveyQuestion, answers: SurveyAnswers, allQuestions: SurveyQuestion[], customFieldValues?: CustomFieldValueMap): StatementRow[];
|
|
568
|
+
declare function getVisibleMcqOptionsForAnswers(question: SurveyQuestion, answers: SurveyAnswers, allQuestions: SurveyQuestion[], customFieldValues?: CustomFieldValueMap): McqOption[];
|
|
569
|
+
declare function getVisibleRankOrderOptionsForAnswers(question: SurveyQuestion, answers: SurveyAnswers, allQuestions: SurveyQuestion[], customFieldValues?: CustomFieldValueMap): RankOrderOption[];
|
|
570
|
+
declare function getVisibleScaleColumnsForAnswers(question: SurveyQuestion, answers: SurveyAnswers, allQuestions: SurveyQuestion[], customFieldValues?: CustomFieldValueMap): ScaleColumn[];
|
|
571
|
+
declare function getVisibleMatrixItemsForAnswers(question: SurveyQuestion, answers: SurveyAnswers, allQuestions: SurveyQuestion[], customFieldValues?: CustomFieldValueMap): {
|
|
572
|
+
statementRows: StatementRow[];
|
|
573
|
+
scaleColumns: ScaleColumn[];
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
declare function resolveQuestionDisplayText(question: SurveyQuestion, context: LogicContext): string;
|
|
577
|
+
declare function applyQuestionDisplayVariants(questions: SurveyQuestion[], context: LogicContext): SurveyQuestion[];
|
|
578
|
+
|
|
579
|
+
declare function computeActivePathQuestionNumbers(pages: SurveyPage[], values: SurveyAnswers, allQuestions: SurveyQuestion[], customFieldValues?: CustomFieldValueMap): Map<string, number>;
|
|
580
|
+
declare function applyActivePathQuestionNumbers(questions: SurveyQuestion[], numbers: Map<string, number>): SurveyQuestion[];
|
|
581
|
+
|
|
582
|
+
declare function matrixColumnStoredValue(column: ScaleColumn): string | null;
|
|
583
|
+
|
|
584
|
+
declare function normalizeRankOrderAnswers(value: unknown): RankOrderAnswers;
|
|
585
|
+
declare function buildRankOrderFromOrderedOptionIds(optionIds: string[]): RankOrderAnswers;
|
|
586
|
+
declare function getOrderedOptionIdsFromRanks(answers: RankOrderAnswers, optionIds: string[]): string[];
|
|
587
|
+
declare function assignRankWithoutDuplicates(currentAnswers: RankOrderAnswers, optionId: string, rank: number | undefined): RankOrderAnswers;
|
|
588
|
+
|
|
589
|
+
export { ACTIONS, type AnswerLogic, type AnswerValue, type CfmMatrixQuestion, type CfmMatrixScaleColumn, type CfmMatrixStatementRow, type ContainerMedia, type CsatQuestion, type CsatScaleColumn, type CsatStatementRow, type CustomFieldType, type CustomFieldValue, type CustomFieldValueMap, type DisplayLogic, type FileUploadQuestion, type HeatmapAnswer, type HeatmapClickPoint, type HeatmapQuestion, type HeatmapRegion, type LogicConditionEntity, type MatrixRowAnswers, type McqOption, type McqQuestion, type NpsQuestion, type NpsScalePoint, QUESTION_ACTIVITY_STATE, QUESTION_TYPE, type QuestionDisplayVariant, type QuestionMedia, type QuestionType, type RankOrderAnswers, type RankOrderInteractionMode, type RankOrderOption, type RankOrderOptionDisplay, type RankOrderQuestion, type RatingMatrixQuestion, type RatingMatrixScaleColumn, type RatingMatrixStatementRow, type SavePartialResponseOption, type ScaleColumn, type SkipLogic, type SliderMatrixQuestion, type SliderMatrixStatementRow, type SliderMatrixTickMark, type SpecialPage, type StatementRow, type Survey, type SurveyAction, type SurveyAnswers, type SurveyLanguage, type SurveyPage, type SurveyPhase, type SurveyPhaseFlags, type SurveyQuestion, type TextAndMediaQuestion, type TextInputQuestion, type UploadedFile, type UploadedFileAnswer, type UseSurveySDKProps, type UseSurveySDKReturn, applyActivePathQuestionNumbers, applyQuestionDisplayVariants, assignRankWithoutDuplicates, buildRankOrderFromOrderedOptionIds, computeActivePathQuestionNumbers, formatAnswerForDisplay, getOrderedOptionIdsFromRanks, getVisibleMatrixItemsForAnswers, getVisibleMcqOptions, getVisibleMcqOptionsForAnswers, getVisibleRankOrderOptions, getVisibleRankOrderOptionsForAnswers, getVisibleScaleColumns, getVisibleScaleColumnsForAnswers, getVisibleStatementRows, getVisibleStatementRowsForAnswers, matrixColumnStoredValue, normalizeRankOrderAnswers, resolveQuestionDisplayText, resolveSurveyQuestionPlaceholders, useSurveySDK };
|