@explorer02/cfm-survey-sdk 0.2.0 → 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 -64
  9. package/templates/AGENT.md +15 -7
  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 +84 -0
  14. package/templates/docs/00-integration/constraints.md +65 -3
  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 +77 -89
  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 +44 -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 +24 -80
  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 +25 -22
  69. package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +18 -46
  70. package/templates/docs/03-ui-specs/09-slider-matrix.md +2 -2
  71. package/templates/docs/03-ui-specs/10-file-upload.md +2 -2
  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 +14 -13
  77. package/templates/docs/03-ui-specs/shared/custom-slider-track.md +3 -3
  78. package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +6 -1
  79. package/templates/docs/MANIFEST.json +454 -67
  80. package/templates/docs/index.md +84 -29
  81. package/templates/docs/templates/Question.tsx +310 -0
  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 +115 -49
  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
@@ -0,0 +1,100 @@
1
+ # Rank Order Architectural Blueprint
2
+
3
+ > **UI spec (authoritative):** `03-ui-specs/14-rank-order.md`
4
+ > **Reference implementation:** `apps/client/src/components/RankOrderScale.tsx`
5
+ > **Target Component:** `RankOrderScale`
6
+ > **Handles:** `type: 'RANK_ORDER'`
7
+
8
+ ## Core Responsibility
9
+
10
+ Render rankable options in either **dropdown** or **drag-and-drop** mode, support three option display variants (text only, image only, text and image), and bubble rank assignments via `onSelect`.
11
+
12
+ ## Props Contract
13
+
14
+ ```typescript
15
+ type RankOrderScaleProps = {
16
+ question: RankOrderQuestion;
17
+ selectedValue?: RankOrderAnswers;
18
+ onSelect: (value: RankOrderAnswers) => void;
19
+ };
20
+ ```
21
+
22
+ ## State Management
23
+
24
+ - `selectedValue` from SDK is source of truth — do not duplicate answer state locally
25
+ - Dropdown mode: use `assignRankWithoutDuplicates` from SDK when a rank changes
26
+ - Drag-and-drop mode: use `buildRankOrderFromOrderedOptionIds` after reorder
27
+
28
+ ## Layout Orchestrator
29
+
30
+ ```tsx
31
+ export function RankOrderScale({ question, selectedValue, onSelect }: RankOrderScaleProps) {
32
+ if (question.interactionMode === 'dragAndDrop') {
33
+ return <DragDropRankLayout ... />;
34
+ }
35
+ return <DropdownRankLayout ... />;
36
+ }
37
+ ```
38
+
39
+ ## Dropdown Mode
40
+
41
+ - One row per visible option
42
+ - Left: rank `<select>` with `-` (unassigned) and `1..N`
43
+ - Selecting rank `R` clears `R` from any other option (SDK helper)
44
+ - Option content depends on `question.optionDisplay`
45
+ - **Image URLs:** prefer `option.imageUrl` over `option.previewImageUrl` — preview `*_p.*` URLs often return 403 on CloudFront
46
+
47
+ ## Drag-and-Drop Mode
48
+
49
+ - Use `@dnd-kit/core` + `@dnd-kit/sortable` for smooth reorder
50
+ - List order maps to ranks: position 0 → rank 1
51
+ - Show rank badge on each row
52
+ - Provide Up/Down buttons for keyboard accessibility
53
+
54
+ ## Wiring in Question.tsx
55
+
56
+ ```typescript
57
+ import {
58
+ QUESTION_TYPE,
59
+ getVisibleRankOrderOptionsForAnswers,
60
+ } from '@explorer02/cfm-survey-sdk';
61
+
62
+ const rankOrderQuestion = useMemo(() => {
63
+ if (question.type !== QUESTION_TYPE.RANK_ORDER) return null;
64
+ return {
65
+ ...question,
66
+ options: getVisibleRankOrderOptionsForAnswers(
67
+ question,
68
+ allAnswers,
69
+ allQuestions,
70
+ customFieldValues
71
+ ),
72
+ };
73
+ }, [question, allAnswers, allQuestions, customFieldValues]);
74
+
75
+ {question.type === QUESTION_TYPE.RANK_ORDER && rankOrderQuestion && (
76
+ <RankOrderScale
77
+ question={rankOrderQuestion}
78
+ selectedValue={...}
79
+ onSelect={onSelect}
80
+ />
81
+ )}
82
+ ```
83
+
84
+ ## Dependencies
85
+
86
+ Add to client `package.json`:
87
+
88
+ - `@dnd-kit/core`
89
+ - `@dnd-kit/sortable`
90
+ - `@dnd-kit/utilities`
91
+
92
+ ## SDK Integration Checklist (agent)
93
+
94
+ - [ ] Type literal: `QUESTION_TYPE.RANK_ORDER`
95
+ - [ ] Answer stored as: `RankOrderAnswers`
96
+ - [ ] onAction CHANGE: `{ questionId, answerValue: RankOrderAnswers }`
97
+ - [ ] Visibility helper: `getVisibleRankOrderOptionsForAnswers(..., customFieldValues?)`
98
+ - [ ] Rank utils: `assignRankWithoutDuplicates`, `buildRankOrderFromOrderedOptionIds`, `normalizeRankOrderAnswers`
99
+ - [ ] Prefer `option.imageUrl` over `previewImageUrl`
100
+ - [ ] Matrix row: [`question-type-sdk-matrix.md#rank_order`](../00-integration/question-type-sdk-matrix.md#rank_order)
@@ -1,48 +1,51 @@
1
1
  # Client Components Overview
2
2
 
3
- > Wiring blueprints for React components. **Authoritative UI details** are in [`03-ui-specs/`](../03-ui-specs/README.md) (reference-client driven).
4
- > This folder documents props, `onSelect` wiring, and dispatcher architecture.
3
+ > Wiring blueprints for React components. **Authoritative UI details** are in [`03-ui-specs/`](../03-ui-specs/README.md).
4
+ > **Required files gate:** [`component-checklist.md`](../00-integration/component-checklist.md)
5
+ > **Dispatcher template:** [`templates/Question.tsx`](../templates/Question.tsx)
6
+ > Read blueprints **per type** from `MANIFEST.json` after survey inventory — not all files are needed for every survey.
5
7
 
6
8
  ## Component Architecture
7
9
 
8
- The UI is driven by a single top-level `SurveyPage` component which iterates over the `currentQuestions` array and passes each `SurveyQuestion` object to the `Question` dispatcher component.
10
+ The UI is driven by `SurveyPage`, which routes by `state.phase` and renders `Question` for each item in `currentQuestions`.
9
11
 
10
12
  ```
11
- SurveyPage (Top-level orchestrator)
13
+ SurveyPage (phase router)
12
14
 
13
- ├── Header (Branding/Logo)
14
- ├── ProgressBar
15
- ├── LanguageSelector
16
- ├── Footer
15
+ ├── IntroPage / PausedPage / EndPage (special phases)
17
16
 
18
- └── Question (Dispatcher, mapped over `currentQuestions`)
19
-
20
- ├── RatingScale (handles 'rating' and 'rating_scale')
21
- ├── CsatScale (handles 'csat')
22
- ├── LikertMatrixScale (handles 'matrix' CFM_MATRIX)
23
- ├── CsatMatrixScale (handles 'matrix' CSAT_MATRIX / 'rating_matrix')
24
- ├── SliderMatrixScale (handles 'slider_matrix')
25
- ├── FileUploadScale (handles 'file_upload')
26
-
27
- ├── (Inline UI for 'radio', 'text', 'text_and_media')
28
-
29
- └── Shared Sub-Components:
30
- ├── CustomSliderTrack (used by csat/matrix sliders)
31
- └── MatrixDropdown (used by matrix dropdowns)
17
+ └── SurveyContent (phase.kind === 'content')
18
+ ├── Header
19
+ ├── ProgressBar
20
+ ├── LanguageSelector
21
+ ├── Question × N (dispatcher)
22
+ ├── Back / Next|Submit nav
23
+ └── Footer
32
24
  ```
33
25
 
34
- ## Styling Approach
26
+ ## Question dispatcher (11 types)
35
27
 
36
- - Built entirely with **Tailwind CSS**.
37
- - **No external UI libraries** (no Material UI, Chakra, etc.).
38
- - The default brand colour is Telekom Magenta: `#e20074`.
39
- - The UI follows a strict, clean, modern corporate aesthetic (card-based layout, subtle borders, pink accents on selection).
28
+ `Question` switches on `question.type` / `QUESTION_TYPE` (no `subType`):
29
+
30
+ | Type | Component |
31
+ |------|-----------|
32
+ | `NPS_SCALE` | `RatingScale` |
33
+ | `MCQ`, `TEXTFIELD`, `TEXT_AND_MEDIA` | Inline in `Question` |
34
+ | `CFM_MATRIX` | `LikertMatrixScale` |
35
+ | `CSAT_MATRIX`, `RATING_MATRIX` | `CsatMatrixScale` |
36
+ | `SLIDER_MATRIX` | `SliderMatrixScale` |
37
+ | `FILE_UPLOAD` | `FileUploadScale` |
38
+ | `HEATMAP` | `HeatmapScale` |
39
+ | `RANK_ORDER` | `RankOrderScale` |
40
40
 
41
- ## The `Question` Dispatcher
41
+ Shared: `CustomSliderTrack`, `MatrixDropdown`
42
42
 
43
- The `Question` component is the heart of the rendering engine. It receives a `SurveyQuestion` union type and switches on `question.type` (and `question.subType` for matrices) to render the correct specialized scale component.
43
+ ## Styling Approach
44
44
 
45
- See `02-question.md` for details on the dispatcher logic.
45
+ - Built entirely with **Tailwind CSS**.
46
+ - **No external UI libraries** (no Material UI, Chakra, etc.).
47
+ - Default brand colour: Telekom Magenta `#e20074`.
48
+ - Card-based layout, subtle borders, pink accents on selection.
46
49
 
47
50
  ## Files in This Folder
48
51
 
@@ -50,14 +53,19 @@ See `02-question.md` for details on the dispatcher logic.
50
53
  |------|-----------|
51
54
  | `01-survey-page.md` | `SurveyPage` orchestrator |
52
55
  | `02-question.md` | `Question` dispatcher & inline types |
53
- | `03-rating-scale.md` | `RatingScale` (NPS/Stars) |
54
- | `04-csat-scale.md` | `CsatScale` (Emoji/Star CSAT) |
55
- | `05-csat-matrix-scale.md` | `CsatMatrixScale` (Satisfaction Grid) |
56
- | `06-likert-matrix-scale.md` | `LikertMatrixScale` (Text Grid) |
57
- | `07-slider-matrix-scale.md` | `SliderMatrixScale` (Sliders Grid) |
56
+ | `03-rating-scale.md` | `RatingScale` (NPS) |
57
+ | `04-star-rating-scale.md` | Legacy star patterns (deprecated) |
58
+ | `05-csat-matrix-scale.md` | `CsatMatrixScale` |
59
+ | `06-likert-matrix-scale.md` | `LikertMatrixScale` |
60
+ | `07-slider-matrix-scale.md` | `SliderMatrixScale` |
58
61
  | `08-file-upload-scale.md` | `FileUploadScale` |
59
- | `09-custom-slider-track.md` | `CustomSliderTrack` (Emoji thumbs) |
62
+ | `09-custom-slider-track.md` | `CustomSliderTrack` |
60
63
  | `10-header-footer.md` | `Header` & `Footer` |
61
64
  | `11-progress-bar.md` | `ProgressBar` |
62
65
  | `12-language-selector.md` | `LanguageSelector` |
63
66
  | `13-matrix-dropdown.md` | `MatrixDropdown` |
67
+ | `14-intro-page.md` | `IntroPage` |
68
+ | `15-end-page.md` | `EndPage` |
69
+ | `16-paused-page.md` | `PausedPage` |
70
+ | `17-heatmap-scale.md` | `HeatmapScale` |
71
+ | `18-rank-order-scale.md` | `RankOrderScale` |
@@ -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)