@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.
- 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 -64
- package/templates/AGENT.md +15 -7
- 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 +84 -0
- package/templates/docs/00-integration/constraints.md +65 -3
- package/templates/docs/00-integration/custom-field-logic-and-navigation.md +174 -0
- package/templates/docs/00-integration/display-logic-and-navigation.md +49 -0
- package/templates/docs/00-integration/end-page-logic.md +64 -0
- package/templates/docs/00-integration/partial-save-and-recovery.md +74 -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 +242 -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 +77 -89
- 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 +12 -3
- package/templates/docs/01-components/07-slider-matrix-scale.md +11 -2
- package/templates/docs/01-components/08-file-upload-scale.md +10 -1
- 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 +3 -1
- 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 +100 -0
- package/templates/docs/01-components/README.md +44 -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 +13 -2
- 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 +86 -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 +24 -80
- package/templates/docs/03-ui-specs/01-rating.md +12 -54
- package/templates/docs/03-ui-specs/02-radio.md +21 -33
- package/templates/docs/03-ui-specs/03-text.md +2 -2
- package/templates/docs/03-ui-specs/04-csat.md +38 -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 +25 -22
- package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +18 -46
- package/templates/docs/03-ui-specs/09-slider-matrix.md +2 -2
- package/templates/docs/03-ui-specs/10-file-upload.md +2 -2
- package/templates/docs/03-ui-specs/11-text-and-media.md +29 -29
- package/templates/docs/03-ui-specs/12-survey-chrome.md +20 -14
- package/templates/docs/03-ui-specs/13-heatmap.md +73 -0
- package/templates/docs/03-ui-specs/14-rank-order.md +59 -0
- package/templates/docs/03-ui-specs/README.md +14 -13
- package/templates/docs/03-ui-specs/shared/custom-slider-track.md +3 -3
- package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +6 -1
- package/templates/docs/MANIFEST.json +454 -67
- package/templates/docs/index.md +84 -29
- package/templates/docs/templates/Question.tsx +310 -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 +115 -49
- package/templates/docs/templates/survey-inventory.schema.json +72 -0
- package/templates/docs/templates/verify-agent-build.sh +53 -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,73 @@
|
|
|
1
|
+
# UI Spec: Heatmap (`type: 'HEATMAP'`)
|
|
2
|
+
|
|
3
|
+
> **Implement from this spec** (npm installs). Monorepo reference: `apps/client/src/components/HeatmapScale.tsx`
|
|
4
|
+
> **SDK type:** `HeatmapQuestion` — `fetchSurvey/types/heatmap.ts`
|
|
5
|
+
> **Component blueprint:** `01-components/17-heatmap-scale.md`
|
|
6
|
+
|
|
7
|
+
## Config Inventory
|
|
8
|
+
|
|
9
|
+
| Field | Implemented | UI impact |
|
|
10
|
+
|-------|-------------|-----------|
|
|
11
|
+
| `questionText` | ✅ (shell) | Bold title + required asterisk |
|
|
12
|
+
| `questionDescription` | ✅ (shell) | Instruction text below title |
|
|
13
|
+
| `required` | ✅ (shell + SDK) | Asterisk + validation on NEXT |
|
|
14
|
+
| `imageUrl` | ✅ | Center-aligned interactive image |
|
|
15
|
+
| `maxClicksAllowed` | ✅ | Footer hint count; blocks new clicks at limit |
|
|
16
|
+
| `regions` | ❌ (respondent UI) | Logic only — not rendered on survey |
|
|
17
|
+
|
|
18
|
+
## Layout Anatomy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
[Question shell: title *, description]
|
|
22
|
+
[Heatmap container — relative, inline-block, max-width 100%]
|
|
23
|
+
[<img> — object-contain, display block, crosshair cursor]
|
|
24
|
+
[Spot overlay — absolute inset-0, pointer-events-none]
|
|
25
|
+
[Orange circle markers at normalized x/y positions]
|
|
26
|
+
[Footer hint — info icon + max spots text]
|
|
27
|
+
[Validation error — from Question shell]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Spot Marker Visual Spec
|
|
31
|
+
|
|
32
|
+
| Property | Value |
|
|
33
|
+
|----------|-------|
|
|
34
|
+
| Shape | Circle |
|
|
35
|
+
| Diameter | 16px |
|
|
36
|
+
| Fill | `#F97316` |
|
|
37
|
+
| Border | 2px solid `#FFFFFF` |
|
|
38
|
+
| Shadow | `0 1px 3px rgba(0,0,0,0.25)` |
|
|
39
|
+
| Position | `left: x * 100%`, `top: y * 100%`, `transform: translate(-50%, -50%)` |
|
|
40
|
+
|
|
41
|
+
## Interactive States
|
|
42
|
+
|
|
43
|
+
| State | Behavior |
|
|
44
|
+
|-------|----------|
|
|
45
|
+
| Image loading | Spinner overlay; clicks disabled |
|
|
46
|
+
| Ready | `cursor: crosshair` on image |
|
|
47
|
+
| At max clicks | Block new adds; allow remove |
|
|
48
|
+
| Removing last spot | `onSelect(undefined)` |
|
|
49
|
+
|
|
50
|
+
## Footer Hint Text
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
ⓘ You can select up to {maxClicksAllowed} spot(s). To change your selection, simply click on the same spot again to remove it.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use singular "spot" when `maxClicksAllowed === 1`.
|
|
57
|
+
|
|
58
|
+
## Answer Mutation
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
onSelect(HeatmapAnswer | undefined)
|
|
62
|
+
// HeatmapAnswer = Array<{ id: string; x: number; y: number }>
|
|
63
|
+
// x, y normalized 0–1 relative to rendered image bounds
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Agent Checklist
|
|
67
|
+
|
|
68
|
+
- [ ] Click handler on `<img>` element (not overlay) for precise coordinates
|
|
69
|
+
- [ ] `inline-block` wrapper so spots align with image bounds
|
|
70
|
+
- [ ] Toggle-remove within 14px hit radius
|
|
71
|
+
- [ ] Wait for `onLoad` before accepting clicks
|
|
72
|
+
- [ ] Percentage-positioned spots (survives resize)
|
|
73
|
+
- [ ] Do NOT render region overlays on respondent UI
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Rank Order UI Spec (`RANK_ORDER`)
|
|
2
|
+
|
|
3
|
+
> **Reference:** `02-reference/question-types/13-rank-order.md`
|
|
4
|
+
> **Blueprint:** `01-components/18-rank-order-scale.md`
|
|
5
|
+
|
|
6
|
+
## Interaction Modes
|
|
7
|
+
|
|
8
|
+
### Dropdown (`interactionMode: 'dropdown'`)
|
|
9
|
+
|
|
10
|
+
| Element | Behavior |
|
|
11
|
+
|---------|----------|
|
|
12
|
+
| Rank select | `-` (unassigned) or `1..N` per option row |
|
|
13
|
+
| Duplicate ranks | Selecting rank R on option A clears R from any other option |
|
|
14
|
+
| Layout | Rank select on left, option content on right |
|
|
15
|
+
|
|
16
|
+
### Drag and Drop (`interactionMode: 'dragAndDrop'`)
|
|
17
|
+
|
|
18
|
+
| Element | Behavior |
|
|
19
|
+
|---------|----------|
|
|
20
|
+
| Drag handle | Six-dot grip on left; pointer + keyboard sensors |
|
|
21
|
+
| Rank badge | Circular badge showing 1-based position |
|
|
22
|
+
| Reorder | List order determines rank; smooth transform during drag |
|
|
23
|
+
| Up/Down buttons | Keyboard fallback on right side of each row |
|
|
24
|
+
|
|
25
|
+
## Option Display Variants
|
|
26
|
+
|
|
27
|
+
| `optionDisplay` | Render |
|
|
28
|
+
|-----------------|--------|
|
|
29
|
+
| `textOnly` | Full-width text label only |
|
|
30
|
+
| `imageOnly` | Large square thumbnail only (no label) |
|
|
31
|
+
| `textAndImage` | Thumbnail + text label side by side |
|
|
32
|
+
|
|
33
|
+
Use `dangerouslySetInnerHTML` for option labels (HTML from builder).
|
|
34
|
+
|
|
35
|
+
## Validation UX
|
|
36
|
+
|
|
37
|
+
- Required + `requireRankAll`: every visible option must have a unique rank from 1..N
|
|
38
|
+
- Required + not `requireRankAll`: at least one visible option ranked
|
|
39
|
+
- SDK surfaces `validationError` on the question shell — show the standard error banner
|
|
40
|
+
|
|
41
|
+
## Styling
|
|
42
|
+
|
|
43
|
+
Match MCQ card styling:
|
|
44
|
+
|
|
45
|
+
- Border: `#e5e5e5` default, `#e20074` when actively ranked (optional highlight)
|
|
46
|
+
- Background hover: `hover:bg-gray-50/50`
|
|
47
|
+
- Rank badge: `#fdf2f8` background, `#e20074` text
|
|
48
|
+
|
|
49
|
+
## Accessibility
|
|
50
|
+
|
|
51
|
+
- Each rank select: `aria-label="Rank for {option label}"`
|
|
52
|
+
- Drag handle: `aria-label="Drag to reorder {option label}"`
|
|
53
|
+
- Up/Down: disabled on first/last item
|
|
54
|
+
|
|
55
|
+
## Do Not
|
|
56
|
+
|
|
57
|
+
- Store ranks in local component state without syncing to `onSelect`
|
|
58
|
+
- Submit option labels — submit rank numbers via SDK formatter only
|
|
59
|
+
- Hardcode logic operators in the client — all conditions are SDK-evaluated
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# UI Specifications — Reference Implementation Guide
|
|
2
2
|
|
|
3
|
-
> **
|
|
4
|
-
>
|
|
3
|
+
> **For npm installs:** implement from these specs + [`templates/Question.tsx`](../templates/Question.tsx).
|
|
4
|
+
> **For monorepo devs:** Reference client at `apps/client/src/components/` aligns with SDK types — trust `03-ui-specs/`, `templates/Question.tsx`, and exported types.
|
|
5
|
+
> Read the spec for **each question type present** in the fetched survey before writing React code.
|
|
5
6
|
|
|
6
7
|
## How to Read a UI Spec
|
|
7
8
|
|
|
@@ -37,14 +38,14 @@ Each file in this folder follows the same structure:
|
|
|
37
38
|
| Spec file | Reference component | `question.type` |
|
|
38
39
|
|-----------|---------------------|-----------------|
|
|
39
40
|
| [00-question-shell.md](00-question-shell.md) | `Question.tsx` | All (wrapper) |
|
|
40
|
-
| [01-rating.md](01-rating.md) | `RatingScale.tsx` | `
|
|
41
|
-
| [02-radio.md](02-radio.md) | `Question.tsx` inline | `
|
|
42
|
-
| [03-text.md](03-text.md) | `Question.tsx` inline | `
|
|
43
|
-
| [04-csat.md](04-csat.md) | `
|
|
44
|
-
| [05-rating-scale.md](05-rating-scale.md) |
|
|
45
|
-
| [06-slider.md](06-slider.md) |
|
|
46
|
-
| [07-matrix-cfm.md](07-matrix-cfm.md) | `LikertMatrixScale.tsx` | `
|
|
47
|
-
| [08-matrix-csat-rating.md](08-matrix-csat-rating.md) | `CsatMatrixScale.tsx` |
|
|
41
|
+
| [01-rating.md](01-rating.md) | `RatingScale.tsx` | `nps` |
|
|
42
|
+
| [02-radio.md](02-radio.md) | `Question.tsx` inline | `mcq` |
|
|
43
|
+
| [03-text.md](03-text.md) | `Question.tsx` inline | `text_input` |
|
|
44
|
+
| [04-csat.md](04-csat.md) | `CsatMatrixScale.tsx` | `csat` |
|
|
45
|
+
| [05-rating-scale.md](05-rating-scale.md) | `RatingScale.tsx` | `star_rating` |
|
|
46
|
+
| [06-slider.md](06-slider.md) | `CustomSliderTrack.tsx` | `slider` |
|
|
47
|
+
| [07-matrix-cfm.md](07-matrix-cfm.md) | `LikertMatrixScale.tsx` | `cfm_matrix` |
|
|
48
|
+
| [08-matrix-csat-rating.md](08-matrix-csat-rating.md) | `CsatMatrixScale.tsx` | `rating_matrix` |
|
|
48
49
|
| [09-slider-matrix.md](09-slider-matrix.md) | `SliderMatrixScale.tsx` | `slider_matrix` |
|
|
49
50
|
| [10-file-upload.md](10-file-upload.md) | `FileUploadScale.tsx` | `file_upload` |
|
|
50
51
|
| [11-text-and-media.md](11-text-and-media.md) | `Question.tsx` inline | `text_and_media` |
|
|
@@ -54,7 +55,7 @@ Each file in this folder follows the same structure:
|
|
|
54
55
|
|
|
55
56
|
## NPS Traffic-Light Colors
|
|
56
57
|
|
|
57
|
-
Use
|
|
58
|
+
Use accent colors from SDK options — never invent colors for NPS:
|
|
58
59
|
|
|
59
60
|
| Value | Hex |
|
|
60
61
|
|-------|-----|
|
|
@@ -72,8 +73,8 @@ Use `option.color` from SDK — never invent colors:
|
|
|
72
73
|
|
|
73
74
|
## When to Read
|
|
74
75
|
|
|
75
|
-
After Phase 3 in [`index.md`](../index.md), for each question in
|
|
76
|
+
After Phase 3 in [`index.md`](../index.md), for each question in the fetched survey:
|
|
76
77
|
|
|
77
78
|
1. Read [`02-reference/question-types/`](../02-reference/question-types/) for data shape
|
|
78
|
-
2. Read matching spec from this folder (see [`MANIFEST.json`](../MANIFEST.json) `
|
|
79
|
+
2. Read matching spec from this folder (see [`MANIFEST.json`](../MANIFEST.json) `questionTypes.{type}.uiSpec`)
|
|
79
80
|
3. Cross-check [`config-field-index.md`](../02-reference/config-field-index.md)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# UI Spec: Custom Slider Track (shared primitive)
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **Implement from this spec** (npm installs). Monorepo reference: `apps/client/src/components/CustomSliderTrack.tsx`
|
|
4
4
|
> **Used by:** `SliderMatrixScale.tsx`, `CsatMatrixScale` (graphics), standalone `slider` (gap)
|
|
5
5
|
|
|
6
6
|
## Layer Architecture
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
| `disabled` | Gray theme, opacity 0.5, no interaction |
|
|
24
24
|
| `displayValues` | Reserved — tooltip always shows on hover/drag in client |
|
|
25
25
|
| `hasSelectedValue` | Reserved |
|
|
26
|
-
| `sliderType: 'graphics'` | Emoji thumb via
|
|
26
|
+
| `sliderType: 'graphics'` | Emoji thumb via client-side react-icons |
|
|
27
27
|
| `ticks` | Discrete tick count + emoji index scale |
|
|
28
28
|
| `reverseScaleOrder` | Flip emoji index calculation |
|
|
29
29
|
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
```typescript
|
|
42
42
|
const idx = Math.round(((value - min) / (max - min)) * ((ticks || 10) - 1));
|
|
43
43
|
const displayIdx = reverseScaleOrder ? (ticks || 10) - 1 - idx : idx;
|
|
44
|
-
|
|
44
|
+
// Map displayIdx to react-icons emoji — proportional mapping is client-implemented (not an SDK export)
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
## Agent Checklist
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# UI Spec: Matrix Dropdown (shared primitive)
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **Implement from this spec** (npm installs). Monorepo reference: `apps/client/src/components/MatrixDropdown.tsx`
|
|
4
4
|
> **Used by:** `LikertMatrixScale`, `CsatMatrixScale` vertical list
|
|
5
5
|
|
|
6
6
|
## Modes
|
|
@@ -30,6 +30,11 @@ if (val === null) {
|
|
|
30
30
|
// When null selected, non-null options disabled
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
- `options: ScaleColumn[]` — matrix scale columns (`id`, `label`)
|
|
36
|
+
- `value` / `onChange` — stored values use `matrixColumnStoredValue(col)` → column **`id`**
|
|
37
|
+
|
|
33
38
|
## Agent Checklist
|
|
34
39
|
|
|
35
40
|
- [ ] Click-outside closes panel
|