@explorer02/cfm-survey-sdk 0.2.4 → 0.2.6
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 +45 -44
- package/dist/cli/index.mjs +43 -42
- package/package.json +1 -6
- package/postinstall.js +2 -1
- package/templates/AGENT.md +3 -3
- package/templates/docs/00-integration/agent-execution-flow.md +46 -27
- package/templates/docs/00-integration/agent-operating-contract.md +13 -5
- package/templates/docs/00-integration/apply-ui-config.md +35 -10
- package/templates/docs/00-integration/aws-deploy.md +117 -3
- package/templates/docs/00-integration/component-checklist.md +8 -4
- package/templates/docs/00-integration/constraints.md +3 -2
- package/templates/docs/00-integration/custom-field-logic-and-navigation.md +1 -1
- package/templates/docs/00-integration/mockup-ui-extraction.md +113 -0
- package/templates/docs/00-integration/placeholders-and-custom-fields-wiring.md +192 -0
- package/templates/docs/00-integration/placeholders-and-tokens.md +2 -1
- package/templates/docs/00-integration/ui-customization-wizard.md +83 -104
- package/templates/docs/00-integration/wizard-api.md +74 -82
- package/templates/docs/00-integration/wizard-chrome-contract.md +210 -0
- package/templates/docs/00-integration/wizard-config-handoff.md +57 -9
- package/templates/docs/00-integration/wizard-preview-build-guide.md +30 -11
- package/templates/docs/00-integration/wizard-question-type-styling.md +4 -2
- package/templates/docs/00-integration/wizard-troubleshooting.md +80 -0
- package/templates/docs/01-components/10-header-footer.md +3 -3
- package/templates/docs/01-components/19-survey-sticky-chrome.md +16 -55
- package/templates/docs/MANIFEST.json +34 -13
- package/templates/docs/index.md +9 -11
- package/templates/docs/templates/Footer.tsx +72 -0
- package/templates/docs/templates/Header.tsx +84 -0
- package/templates/docs/templates/LanguageSelector.tsx +40 -0
- package/templates/docs/templates/PreviewBridgeInit.tsx +13 -0
- package/templates/docs/templates/ProgressBar.tsx +33 -0
- package/templates/docs/templates/Question.tsx +50 -7
- package/templates/docs/templates/SurveyStickyChrome.tsx +19 -5
- package/templates/docs/templates/deploy-to-aws.sh +74 -0
- package/templates/docs/templates/implementation_plan.md +19 -12
- package/templates/docs/templates/verify-agent-build.sh +25 -1
- package/templates/preview-harness/preview-bridge.inline.js +1 -1
- package/templates/previewBridge.ts +131 -38
- package/templates/wizard-dist/assets/{PreviewMock-DgHfrVeb.js → PreviewMock-7peNZK-z.js} +1 -1
- package/templates/wizard-dist/assets/{TypePanel-CFVC3Ptn.js → TypePanel-BxHnE3cm.js} +1 -1
- package/templates/wizard-dist/assets/index-DtZhNwPS.js +34 -0
- package/templates/wizard-dist/index.html +1 -1
- package/templates/wizard-dist/assets/index-DYK3X1e5.js +0 -34
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
> Copy this file to `./implementation_plan.md` in the project root. Fill every section before writing React code.
|
|
4
4
|
>
|
|
5
|
-
> Pipeline: [`agent-operating-contract.md`](../00-integration/agent-operating-contract.md) → [`agent-execution-flow.md`](../00-integration/agent-execution-flow.md)
|
|
5
|
+
> Pipeline: [`agent-operating-contract.md`](../00-integration/agent-operating-contract.md) → [`agent-execution-flow.md`](../00-integration/agent-execution-flow.md)
|
|
6
|
+
> Mockup rules: [`mockup-ui-extraction.md`](../00-integration/mockup-ui-extraction.md)
|
|
6
7
|
|
|
7
8
|
## 0. Project Context
|
|
8
9
|
|
|
9
10
|
- **Framework:** [ ] Next.js App Router [ ] Vite [ ] CRA [ ] Existing app
|
|
10
11
|
- **Package import name:** (from `package.json` — `@explorer02/cfm-survey-sdk` or `@repo/sdk`)
|
|
11
12
|
- **instanceId:** (JWT — wired in SurveyPage)
|
|
12
|
-
- **Branding source:** (client prompt / mockup
|
|
13
|
+
- **Branding source:** (client prompt / mockup — **UI only** per [`mockup-ui-extraction.md`](../00-integration/mockup-ui-extraction.md); optional wizard override via `survey-ui-config.json`)
|
|
13
14
|
|
|
14
15
|
## 1. Data Fetching & State
|
|
15
16
|
|
|
@@ -109,7 +110,8 @@ Read `00-integration/canonical-survey-fixtures.md`. For each matrix question not
|
|
|
109
110
|
|
|
110
111
|
## 3d. Custom field inventory (mandatory when `_c_…` ids found)
|
|
111
112
|
|
|
112
|
-
After fetch, scan `skipLogics`, `displayLogic`, `answerLogic`, and `endPages` for `entityType: 'CUSTOM_FIELD'`.
|
|
113
|
+
After fetch, scan `skipLogics`, `displayLogic`, `answerLogic`, and `endPages` for `entityType: 'CUSTOM_FIELD'`.
|
|
114
|
+
**Do not** infer ids from mockup — see [`placeholders-and-custom-fields-wiring.md`](../00-integration/placeholders-and-custom-fields-wiring.md).
|
|
113
115
|
|
|
114
116
|
| `_c_` id | fieldType | used in (skip/display/answer/end) | logic field (e.g. CASE_SENSITIVE_TEXT) | CRM value | populated in `lib/customFieldValues.ts`? |
|
|
115
117
|
|----------|-----------|-----------------------------------|----------------------------------------|-----------|---------------------------------------------|
|
|
@@ -121,9 +123,17 @@ Wire map in **both** places: `useSurveySDK({ options: { customFieldValues } })`
|
|
|
121
123
|
|
|
122
124
|
See `00-integration/custom-field-logic-and-navigation.md` and `00-integration/client-lib-folder.md`.
|
|
123
125
|
|
|
126
|
+
## 3d-b. Placeholder inventory (from fetched question text)
|
|
127
|
+
|
|
128
|
+
Scan fetched survey for `{{TOKEN}}` and `{{SURVEY_QUESTION-:-id}}` — **not** from mockup. See [`placeholders-and-custom-fields-wiring.md`](../00-integration/placeholders-and-custom-fields-wiring.md).
|
|
129
|
+
|
|
130
|
+
| Token in fetch | Key in `SURVEY_PLACEHOLDERS` | Example value | Question ids |
|
|
131
|
+
|----------------|------------------------------|---------------|--------------|
|
|
132
|
+
| | | | |
|
|
133
|
+
|
|
124
134
|
## 3e. Logic inventory (from fetched survey)
|
|
125
135
|
|
|
126
|
-
Scan `survey.pages` for logic flags. Fill after fetch:
|
|
136
|
+
Scan `survey.pages` for logic flags. Fill after fetch — **not** from mockup:
|
|
127
137
|
|
|
128
138
|
| questionId | skipLogics | displayLogic | answerLogic (options/rows/cols) | customField refs (`_c_…`) |
|
|
129
139
|
|------------|------------|--------------|----------------------------------|---------------------------|
|
|
@@ -182,7 +192,7 @@ Inventory required config fields per type:
|
|
|
182
192
|
- [ ] `src/styles/survey-theme.css` with `--cfm-*` CSS variables (full template set)
|
|
183
193
|
- [ ] **Wizard preview contract:** `var(--cfm-*)` in chrome/scales + `data-cfm-*` on editable text/logo — see `00-integration/wizard-preview-build-guide.md`
|
|
184
194
|
- [ ] **Wizard per-type styling:** `selectionStyles.ts`, `labelStyles.ts`, per-type tokens — see `00-integration/wizard-question-type-styling.md`
|
|
185
|
-
- [ ] **
|
|
195
|
+
- [ ] **Wizard `surveyTypes`:** all 11 literals in seed (mockup may show NPS only — wizard still customizes all types)
|
|
186
196
|
- [ ] `previewBridge.ts` wired for wizard live preview (see `ui-customization-wizard.md`)
|
|
187
197
|
- [ ] If `survey-ui-config.json` exists: apply per `apply-ui-config.md` (Phase 5 draft or Phase 6c final)
|
|
188
198
|
|
|
@@ -190,13 +200,10 @@ Inventory required config fields per type:
|
|
|
190
200
|
|
|
191
201
|
See `wizard-config-handoff.md`.
|
|
192
202
|
|
|
193
|
-
- [ ] `customize
|
|
194
|
-
- [ ]
|
|
195
|
-
- [ ]
|
|
196
|
-
- [ ]
|
|
197
|
-
- [ ] Applied from `survey-ui-config.final.json` (AWS) or `survey-ui-config.json` (local)
|
|
198
|
-
- [ ] Every diff path applied (count matches)
|
|
199
|
-
- [ ] `confirm-ui-config` run (AWS)
|
|
203
|
+
- [ ] `npx cfm-sdk customize` ran (default) and exited 0 — client saved on same machine
|
|
204
|
+
- [ ] OR `customize-ui` + EC2 link if client on remote device
|
|
205
|
+
- [ ] `survey-ui-config.json` written (or `.final.json` + `.diff.md` for EC2)
|
|
206
|
+
- [ ] Applied per `apply-ui-config.md`
|
|
200
207
|
- [ ] Verify + build re-run after apply
|
|
201
208
|
|
|
202
209
|
## 6. Submit & Thank You
|
|
@@ -67,11 +67,35 @@ echo "OK: survey-ui-config.json present"
|
|
|
67
67
|
|
|
68
68
|
CHROME_HOOKS=$(grep -rE "data-cfm-(logo|btn-next|survey-title)" src/ components/ app/ 2>/dev/null || true)
|
|
69
69
|
if [ -z "$CHROME_HOOKS" ]; then
|
|
70
|
-
echo "FAIL: No data-cfm-* chrome hooks found — see wizard-
|
|
70
|
+
echo "FAIL: No data-cfm-* chrome hooks found — copy templates/docs/templates/Header.tsx etc.; see wizard-chrome-contract.md"
|
|
71
71
|
exit 1
|
|
72
72
|
fi
|
|
73
73
|
echo "OK: data-cfm-* chrome hooks present"
|
|
74
74
|
|
|
75
|
+
# Wizard layout toggle targets (each must exist for live preview toggles)
|
|
76
|
+
for hook in "data-cfm-logo" "data-cfm-company" "data-cfm-progress" "cfm-footer" "data-cfm-question-number" "data-cfm-required"; do
|
|
77
|
+
FOUND=$(grep -rE "$hook" src/ components/ app/ 2>/dev/null || true)
|
|
78
|
+
if [ -z "$FOUND" ]; then
|
|
79
|
+
echo "FAIL: Missing wizard hook $hook — see wizard-chrome-contract.md"
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
done
|
|
83
|
+
echo "OK: wizard layout + branding hooks present"
|
|
84
|
+
|
|
85
|
+
PREVIEW_BRIDGE=""
|
|
86
|
+
for candidate in src/lib/previewBridge.ts lib/previewBridge.ts; do
|
|
87
|
+
if [ -f "$candidate" ]; then PREVIEW_BRIDGE="$candidate"; break; fi
|
|
88
|
+
done
|
|
89
|
+
if [ -z "$PREVIEW_BRIDGE" ]; then
|
|
90
|
+
echo "FAIL: src/lib/previewBridge.ts missing — copy from templates/previewBridge.ts"
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
if ! grep -q "layoutFlags" "$PREVIEW_BRIDGE"; then
|
|
94
|
+
echo "FAIL: previewBridge.ts outdated — re-copy from templates/previewBridge.ts (needs layoutFlags handler)"
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
echo "OK: previewBridge.ts present with layoutFlags"
|
|
98
|
+
|
|
75
99
|
REQUIRED_TYPES=(MCQ TEXTFIELD NPS_SCALE CFM_MATRIX CSAT_MATRIX RATING_MATRIX SLIDER_MATRIX FILE_UPLOAD TEXT_AND_MEDIA HEATMAP RANK_ORDER)
|
|
76
100
|
QUESTION_FILE=""
|
|
77
101
|
for candidate in src/components/Question.tsx components/Question.tsx app/components/Question.tsx; do
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
setDisplay('[data-cfm-company]', flags.showCompanyName);
|
|
123
123
|
}
|
|
124
124
|
if (flags.showHeader !== undefined) {
|
|
125
|
-
setDisplay('.cfm-header, header.cfm-header
|
|
125
|
+
setDisplay('.cfm-header, header.cfm-header', flags.showHeader);
|
|
126
126
|
}
|
|
127
127
|
if (flags.showFooter !== undefined) {
|
|
128
128
|
setDisplay('.cfm-footer, footer.cfm-footer', flags.showFooter);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Live preview bridge for cfm-sdk customize wizard.
|
|
3
|
-
* Copy to src/lib/previewBridge.ts and import once in layout.tsx.
|
|
3
|
+
* Copy to src/lib/previewBridge.ts and import once via PreviewBridgeInit in layout.tsx.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Must stay in sync with templates/preview-harness/preview-bridge.inline.js (injected into export-previews HTML).
|
|
6
6
|
*/
|
|
7
7
|
export const PREVIEW_BRIDGE_SNAPSHOT = 'CFM_UI_CONFIG_SNAPSHOT';
|
|
8
8
|
export const PREVIEW_BRIDGE_DELTA = 'CFM_UI_CONFIG_DELTA';
|
|
@@ -13,11 +13,14 @@ export interface ContentPatch {
|
|
|
13
13
|
logoUrl?: string | null;
|
|
14
14
|
surveyTitle?: string;
|
|
15
15
|
companyName?: string;
|
|
16
|
+
browserTabTitle?: string;
|
|
16
17
|
thankYouMessage?: string;
|
|
17
18
|
buttonLabels?: { next?: string; back?: string; submit?: string };
|
|
18
19
|
layoutFlags?: Record<string, boolean | string>;
|
|
19
20
|
footerLinks?: { label: string; url: string }[];
|
|
20
21
|
copyrightText?: string;
|
|
22
|
+
domAttributes?: Record<string, string>;
|
|
23
|
+
previewState?: Record<string, unknown>;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
interface PreviewBridgePayload {
|
|
@@ -48,61 +51,147 @@ function queueCssVars(vars: Record<string, string>): void {
|
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
function
|
|
54
|
+
function applyCssVarsImmediate(vars: Record<string, string>): void {
|
|
52
55
|
const root = document.documentElement;
|
|
56
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
57
|
+
root.style.setProperty(key, value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function setDisplay(selector: string, visible: boolean): void {
|
|
62
|
+
document.querySelectorAll(selector).forEach((el) => {
|
|
63
|
+
(el as HTMLElement).style.display = visible ? '' : 'none';
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function applyContentPatch(patch: ContentPatch): void {
|
|
53
68
|
if (patch.logoUrl !== undefined) {
|
|
54
|
-
|
|
55
|
-
document.querySelectorAll('[data-cfm-logo]').forEach((el) => {
|
|
69
|
+
document.querySelectorAll('[data-cfm-logo], header img, footer img').forEach((el) => {
|
|
56
70
|
const img = el as HTMLImageElement;
|
|
57
71
|
if (patch.logoUrl) {
|
|
58
72
|
img.src = patch.logoUrl;
|
|
59
73
|
img.style.display = '';
|
|
60
|
-
} else {
|
|
74
|
+
} else if (el.hasAttribute('data-cfm-logo')) {
|
|
61
75
|
img.style.display = 'none';
|
|
62
76
|
}
|
|
63
77
|
});
|
|
78
|
+
document.querySelectorAll('[data-cfm-logo-text]').forEach((el) => {
|
|
79
|
+
const htmlEl = el as HTMLElement;
|
|
80
|
+
if (patch.logoUrl) {
|
|
81
|
+
htmlEl.style.display = 'none';
|
|
82
|
+
} else {
|
|
83
|
+
htmlEl.style.display = '';
|
|
84
|
+
htmlEl.classList.remove('hidden');
|
|
85
|
+
}
|
|
86
|
+
});
|
|
64
87
|
}
|
|
88
|
+
|
|
65
89
|
if (patch.companyName !== undefined) {
|
|
66
90
|
document.querySelectorAll('[data-cfm-company]').forEach((el) => {
|
|
67
91
|
el.textContent = patch.companyName ?? '';
|
|
68
92
|
});
|
|
93
|
+
document.querySelectorAll('[data-cfm-logo-text]').forEach((el) => {
|
|
94
|
+
const logoImg = document.querySelector('[data-cfm-logo]') as HTMLImageElement | null;
|
|
95
|
+
const logoHidden = !logoImg || logoImg.style.display === 'none';
|
|
96
|
+
if (logoHidden) {
|
|
97
|
+
el.textContent = patch.companyName ?? el.textContent;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
69
100
|
}
|
|
101
|
+
|
|
70
102
|
if (patch.surveyTitle !== undefined) {
|
|
71
103
|
document.querySelectorAll('[data-cfm-survey-title]').forEach((el) => {
|
|
72
104
|
el.textContent = patch.surveyTitle ?? '';
|
|
73
105
|
});
|
|
74
106
|
}
|
|
107
|
+
|
|
108
|
+
if (patch.browserTabTitle) {
|
|
109
|
+
document.title = patch.browserTabTitle;
|
|
110
|
+
}
|
|
111
|
+
|
|
75
112
|
if (patch.thankYouMessage !== undefined) {
|
|
76
113
|
document.querySelectorAll('[data-cfm-thank-you]').forEach((el) => {
|
|
77
114
|
el.textContent = patch.thankYouMessage ?? '';
|
|
78
115
|
});
|
|
79
116
|
}
|
|
117
|
+
|
|
80
118
|
if (patch.buttonLabels?.next) {
|
|
81
119
|
document.querySelectorAll('[data-cfm-btn-next]').forEach((el) => {
|
|
82
120
|
el.textContent = patch.buttonLabels!.next!;
|
|
83
121
|
});
|
|
84
122
|
}
|
|
123
|
+
|
|
85
124
|
if (patch.buttonLabels?.back) {
|
|
86
125
|
document.querySelectorAll('[data-cfm-btn-back]').forEach((el) => {
|
|
87
126
|
el.textContent = patch.buttonLabels!.back!;
|
|
88
127
|
});
|
|
89
128
|
}
|
|
129
|
+
|
|
90
130
|
if (patch.copyrightText !== undefined) {
|
|
91
131
|
document.querySelectorAll('[data-cfm-copyright]').forEach((el) => {
|
|
92
132
|
el.textContent = patch.copyrightText ?? '';
|
|
93
133
|
});
|
|
94
134
|
}
|
|
135
|
+
|
|
95
136
|
if (patch.footerLinks) {
|
|
96
137
|
const nav = document.querySelector('[data-cfm-footer-links]');
|
|
97
138
|
if (nav) {
|
|
98
139
|
nav.innerHTML = patch.footerLinks
|
|
99
140
|
.map(
|
|
100
141
|
(l) =>
|
|
101
|
-
`<a href="${l.url}" target="_blank" rel="noopener noreferrer" style="color:var(--cfm-footer-link)">${l.label}</a>`,
|
|
142
|
+
`<a href="${l.url}" class="cfm-footer-link" target="_blank" rel="noopener noreferrer" style="color:var(--cfm-footer-link)">${l.label}</a>`,
|
|
102
143
|
)
|
|
103
144
|
.join('');
|
|
104
145
|
}
|
|
105
146
|
}
|
|
147
|
+
|
|
148
|
+
if (patch.layoutFlags) {
|
|
149
|
+
const flags = patch.layoutFlags;
|
|
150
|
+
if (flags.showCompanyName !== undefined) {
|
|
151
|
+
setDisplay('[data-cfm-company]', Boolean(flags.showCompanyName));
|
|
152
|
+
}
|
|
153
|
+
if (flags.showHeader !== undefined) {
|
|
154
|
+
setDisplay('.cfm-header, header.cfm-header', Boolean(flags.showHeader));
|
|
155
|
+
}
|
|
156
|
+
if (flags.showFooter !== undefined) {
|
|
157
|
+
setDisplay('.cfm-footer, footer.cfm-footer', Boolean(flags.showFooter));
|
|
158
|
+
}
|
|
159
|
+
if (flags.showProgressBar !== undefined) {
|
|
160
|
+
setDisplay('.cfm-progress, [data-cfm-progress]', Boolean(flags.showProgressBar));
|
|
161
|
+
}
|
|
162
|
+
if (flags.showLanguageSwitcher !== undefined) {
|
|
163
|
+
setDisplay('[data-cfm-language]', Boolean(flags.showLanguageSwitcher));
|
|
164
|
+
}
|
|
165
|
+
if (flags.showNextButton !== undefined) {
|
|
166
|
+
setDisplay('[data-cfm-btn-next]', Boolean(flags.showNextButton));
|
|
167
|
+
}
|
|
168
|
+
if (flags.showBackButton !== undefined) {
|
|
169
|
+
setDisplay('[data-cfm-btn-back]', Boolean(flags.showBackButton));
|
|
170
|
+
}
|
|
171
|
+
if (flags.showQuestionNumbers !== undefined) {
|
|
172
|
+
setDisplay('[data-cfm-question-number]', Boolean(flags.showQuestionNumbers));
|
|
173
|
+
}
|
|
174
|
+
if (flags.showRequiredAsterisk !== undefined) {
|
|
175
|
+
setDisplay('[data-cfm-required]', Boolean(flags.showRequiredAsterisk));
|
|
176
|
+
}
|
|
177
|
+
if (flags.showFooterLogo !== undefined) {
|
|
178
|
+
setDisplay('[data-cfm-footer-logo]', Boolean(flags.showFooterLogo));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (patch.domAttributes) {
|
|
183
|
+
const root = document.documentElement;
|
|
184
|
+
for (const [attr, value] of Object.entries(patch.domAttributes)) {
|
|
185
|
+
root.setAttribute(attr, value);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const placeholder = patch.previewState?.textfieldPlaceholder;
|
|
190
|
+
if (typeof placeholder === 'string') {
|
|
191
|
+
document.querySelectorAll('[data-cfm-textfield]').forEach((el) => {
|
|
192
|
+
el.setAttribute('placeholder', placeholder);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
106
195
|
}
|
|
107
196
|
|
|
108
197
|
function setLiveEditMode(on: boolean): void {
|
|
@@ -111,43 +200,47 @@ function setLiveEditMode(on: boolean): void {
|
|
|
111
200
|
document.documentElement.classList.toggle('cfm-live-edit', on);
|
|
112
201
|
}
|
|
113
202
|
|
|
114
|
-
|
|
115
|
-
|
|
203
|
+
function handleMessage(event: MessageEvent<PreviewBridgePayload>): void {
|
|
204
|
+
const data = event.data;
|
|
205
|
+
if (!data?.type) return;
|
|
206
|
+
if (
|
|
207
|
+
data.type !== PREVIEW_BRIDGE_SNAPSHOT &&
|
|
208
|
+
data.type !== PREVIEW_BRIDGE_DELTA &&
|
|
209
|
+
data.type !== PREVIEW_BRIDGE_MESSAGE
|
|
210
|
+
) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
116
213
|
|
|
117
|
-
|
|
118
|
-
const data = event.data;
|
|
119
|
-
if (!data?.type) return;
|
|
214
|
+
setLiveEditMode(true);
|
|
120
215
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
data.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return;
|
|
216
|
+
if (data.cssVars) {
|
|
217
|
+
if (data.type === PREVIEW_BRIDGE_DELTA) {
|
|
218
|
+
queueCssVars(data.cssVars);
|
|
219
|
+
} else {
|
|
220
|
+
applyCssVarsImmediate(data.cssVars);
|
|
127
221
|
}
|
|
222
|
+
}
|
|
128
223
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
queueCssVars(data.cssVars);
|
|
134
|
-
} else {
|
|
135
|
-
applyCssVarsImmediate(data.cssVars);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
224
|
+
if (data.contentPatch) {
|
|
225
|
+
applyContentPatch(data.contentPatch);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
138
228
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
};
|
|
229
|
+
export function initPreviewBridge(): () => void {
|
|
230
|
+
if (typeof window === 'undefined') return () => {};
|
|
143
231
|
|
|
144
|
-
window.addEventListener('message',
|
|
145
|
-
return () => window.removeEventListener('message', handler);
|
|
146
|
-
}
|
|
232
|
+
window.addEventListener('message', handleMessage);
|
|
147
233
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
234
|
+
let channel: BroadcastChannel | null = null;
|
|
235
|
+
try {
|
|
236
|
+
channel = new BroadcastChannel('cfm-wizard-preview');
|
|
237
|
+
channel.addEventListener('message', (event) => handleMessage(event as MessageEvent<PreviewBridgePayload>));
|
|
238
|
+
} catch {
|
|
239
|
+
/* BroadcastChannel unavailable */
|
|
152
240
|
}
|
|
241
|
+
|
|
242
|
+
return () => {
|
|
243
|
+
window.removeEventListener('message', handleMessage);
|
|
244
|
+
channel?.close();
|
|
245
|
+
};
|
|
153
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as x,j as e}from"./index-
|
|
1
|
+
import{u as x,j as e}from"./index-DtZhNwPS.js";import{b as t}from"./vendor-BwkXDkd3.js";function p(d=150){const l=x(r=>r.config),[a,s]=t.useState(l);return t.useEffect(()=>{const r=window.setTimeout(()=>s(l),d);return()=>window.clearTimeout(r)},[l,d]),a}const h=t.memo(function(){const l=p(150),a=x(n=>n.logoPreviewDataUrl),{global:s}=l,{layout:r,colorScheme:o,buttons:c}=s,m=t.useMemo(()=>r.borderStyle==="sharp"?"rounded-none":r.borderStyle==="pill"?"rounded-[32px]":"rounded-2xl",[r.borderStyle]),i=t.useMemo(()=>r.fontStyle==="serif"?"Georgia, serif":r.fontStyle==="system"?"system-ui, sans-serif":"Inter, sans-serif",[r.fontStyle]),u=a??s.logo.url,f=t.useMemo(()=>({backgroundColor:o.background,color:o.text,borderColor:o.secondary,fontFamily:i}),[o,i]);return e.jsxs("div",{className:`overflow-hidden border shadow-md ${m}`,style:f,children:[r.showHeader&&e.jsxs("div",{className:"flex items-center gap-3 border-b px-5 py-4",style:{borderColor:o.secondary},children:[u&&e.jsx("img",{src:u,alt:"Logo",className:"max-h-6 w-auto object-contain",loading:"lazy"}),e.jsx("span",{className:"text-xs font-semibold tracking-wider",children:s.companyName})]}),e.jsxs("div",{className:"space-y-6 p-6",children:[r.showProgressBar&&e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("div",{className:"flex justify-between text-[10px] font-semibold text-slate-400",children:[e.jsx("span",{children:"Progress"}),e.jsx("span",{children:"35%"})]}),e.jsx("div",{className:"h-1.5 w-full overflow-hidden rounded-full bg-slate-100",children:e.jsx("div",{className:"h-full w-[35%] rounded-full",style:{backgroundColor:o.accent}})})]}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("h4",{className:"flex items-start gap-1.5 text-sm font-bold leading-snug",children:[r.showQuestionNumbers&&e.jsx("span",{className:"font-medium text-slate-400",children:"Q1."}),e.jsx("span",{children:s.surveyTitle}),r.showRequiredAsterisk&&e.jsx("span",{className:"text-red-500",children:"*"})]}),e.jsx("p",{className:"text-[11px] text-slate-400",children:"How would you rate your overall experience?"}),e.jsx("div",{className:"grid grid-cols-5 gap-2",children:[1,2,3,4,5].map(n=>e.jsx("div",{className:`flex h-9 items-center justify-center border text-xs font-semibold ${r.borderStyle==="pill"?"rounded-full":r.borderStyle==="sharp"?"rounded-none":"rounded-lg"}`,style:n===1?{backgroundColor:o.secondary,borderColor:o.primary,color:o.primary}:{backgroundColor:o.background,borderColor:o.secondary,color:o.text},children:n},n))})]})]}),e.jsxs("div",{className:"flex items-center justify-between border-t bg-slate-50/50 px-6 py-4",children:[r.showBackButton&&e.jsx("span",{className:`border px-3 py-1.5 text-[10px] font-semibold ${r.borderStyle==="pill"?"rounded-full":r.borderStyle==="sharp"?"rounded-none":"rounded-lg"}`,style:{borderColor:o.secondary,color:o.text},children:c.back}),e.jsx("div",{className:"flex-1"}),r.showNextButton&&e.jsx("span",{className:`px-4 py-1.5 text-[10px] font-bold ${r.borderStyle==="pill"?"rounded-full":r.borderStyle==="sharp"?"rounded-none":"rounded-lg"}`,style:{backgroundColor:o.primary,color:o.buttonText},children:c.next})]})]})});export{h as PreviewMock};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as g,j as e,T as f,S as j,R as u,N as t,C as i,a as M,M as L}from"./index-DYK3X1e5.js";import"./vendor-BwkXDkd3.js";function b({values:o,onPatch:r}){return e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(i,{label:"Label text color",value:o.columnLabelColor,onChange:a=>r({columnLabelColor:a})}),e.jsx(i,{label:"Label background",value:o.columnLabelBgColor,onChange:a=>r({columnLabelBgColor:a})})]})}function P({values:o,onPatch:r}){return e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsxs("label",{className:"space-y-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Min hint label"}),e.jsx("input",{className:"w-full rounded-lg border border-white/10 bg-slate-950/50 px-3 py-2 text-sm text-white",value:o.hintMinText,onChange:a=>r({hintMinText:a.target.value})})]}),e.jsxs("label",{className:"space-y-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Max hint label"}),e.jsx("input",{className:"w-full rounded-lg border border-white/10 bg-slate-950/50 px-3 py-2 text-sm text-white",value:o.hintMaxText,onChange:a=>r({hintMaxText:a.target.value})})]}),e.jsx(i,{label:"Hint text color",value:o.hintLabelColor,onChange:a=>r({hintLabelColor:a})}),e.jsx(i,{label:"Hint label background",value:o.hintLabelBgColor,onChange:a=>r({hintLabelBgColor:a})})]})}function p({values:o,onPatch:r,count:a=11}){return e.jsxs("div",{className:"space-y-3",children:[e.jsx(j,{label:"Number label style",value:o.numberLabelMode,onChange:d=>r({numberLabelMode:d}),options:[{value:"traffic",label:"Traffic light (default)"},{value:"monochrome",label:"Monochrome (one color)"},{value:"individual",label:"Individual per number"}]}),o.numberLabelMode==="monochrome"&&e.jsx(i,{label:"Monochrome color",value:o.monochromeNumberColor,onChange:d=>r({monochromeNumberColor:d})}),o.numberLabelMode==="individual"&&e.jsx("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3",children:Array.from({length:a},(d,c)=>e.jsx(i,{label:`#${c}`,value:o.individualNumberColors[c]??"#9CA3AF",onChange:C=>{const x=[...o.individualNumberColors];x[c]=C,r({individualNumberColors:x})}},c))})]})}function s({title:o,children:r}){return e.jsxs("div",{className:"space-y-3 rounded-xl border border-white/5 bg-slate-950/20 p-4",children:[e.jsx("h4",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:o}),r]})}function B({type:o,activeFormat:r}){const a=g(l=>l.config.questionTypes[o]),d=g(l=>l.updateQuestionType),c=g(l=>l.previewMultiStatement),C=g(l=>l.setPreviewMultiStatement),x=g(l=>l.heatmapPreviewPin);if(!a)return e.jsx("p",{className:"text-sm text-slate-500",children:"No configuration available for this type."});const n=l=>d(o,l),S=L.includes(o),T=r.includes("star"),h=r.includes("emoji"),v=r.includes("numbered"),N=r.includes("drag"),w=r.includes("dropdown"),k=r.includes("radio"),m=h||T||v||k;return e.jsxs("div",{className:"space-y-4",children:[S&&e.jsx(f,{label:"Preview multiple statements",checked:c,onChange:C}),o==="MCQ"&&"optionGap"in a&&e.jsx(s,{title:"Option style",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(j,{label:"Option style",value:a.optionStyle??a.cardStyle??"outlined",onChange:l=>n({optionStyle:l}),options:[{value:"outlined",label:"Outlined"},{value:"filled",label:"Filled"},{value:"minimal",label:"Minimal"}]}),e.jsx(u,{label:"Option gap",value:a.optionGap,onChange:l=>n({optionGap:l}),min:0,max:32}),e.jsx(u,{label:"Border radius",value:a.borderRadius,onChange:l=>n({borderRadius:l}),min:0,max:24}),e.jsx(u,{label:"Option padding",value:a.optionPadding??12,onChange:l=>n({optionPadding:l}),min:4,max:24})]})}),o==="TEXTFIELD"&&"defaultPlaceholder"in a&&e.jsx(s,{title:"Text input",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("label",{className:"space-y-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Default placeholder"}),e.jsx("input",{className:"w-full rounded-lg border border-white/10 bg-slate-950/50 px-3 py-2 text-sm text-white",value:a.defaultPlaceholder,onChange:l=>n({defaultPlaceholder:l.target.value})})]}),e.jsx(t,{label:"Input radius (px)",value:a.inputRadius,onChange:l=>n({inputRadius:l}),min:0,max:24}),e.jsx(i,{label:"Border color",value:a.borderColor,onChange:l=>n({borderColor:l})}),e.jsx(i,{label:"Placeholder color",value:a.placeholderColor,onChange:l=>n({placeholderColor:l})})]})}),o==="NPS_SCALE"&&"buttonStyle"in a&&e.jsxs(e.Fragment,{children:[e.jsx(s,{title:"NPS buttons",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(j,{label:"Button style",value:a.buttonStyle,onChange:l=>n({buttonStyle:l}),options:[{value:"standard",label:"Radio"},{value:"numbered",label:"Numbered badges"},{value:"pill",label:"Pill"}]}),e.jsx(i,{label:"Selected fill",value:a.selectedFill,onChange:l=>n({selectedFill:l})}),e.jsx(i,{label:"Track bar",value:a.trackBarColor,onChange:l=>n({trackBarColor:l})}),e.jsx(i,{label:"Track highlight",value:a.trackHighlightColor,onChange:l=>n({trackHighlightColor:l})})]})}),e.jsx(s,{title:"Hint labels",children:e.jsx(P,{values:a,onPatch:n})}),e.jsx(s,{title:"Number labels",children:e.jsx(p,{values:a,onPatch:n})})]}),o==="CFM_MATRIX"&&"rowLabelWidth"in a&&e.jsxs(e.Fragment,{children:[e.jsx(s,{title:"Matrix layout",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(t,{label:"Row label width (px)",value:a.rowLabelWidth,onChange:l=>n({rowLabelWidth:l}),min:120,max:280}),e.jsx(t,{label:"Bipolar column width (%)",value:a.bipolarColumnWidthPercent,onChange:l=>n({bipolarColumnWidthPercent:l}),min:15,max:40})]})}),e.jsx(s,{title:"Label items",children:e.jsx(b,{values:a,onPatch:n})})]}),o==="CSAT_MATRIX"&&"emojiSize"in a&&e.jsxs(e.Fragment,{children:[(h||m)&&e.jsxs(s,{title:`${M.CSAT_MATRIX} — ${r.replace("CSAT_","")}`,children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[h&&e.jsx(t,{label:"Emoji size (px)",value:a.emojiSize,onChange:l=>n({emojiSize:l}),min:16,max:40}),m&&e.jsx(u,{label:"Unselected opacity",value:Math.round(a.unselectedOpacity*100),onChange:l=>n({unselectedOpacity:l/100}),min:10,max:100})]}),e.jsx("p",{className:"text-xs text-slate-500",children:"Selected cell color and focus ring come from Theme → Question card."})]}),e.jsx(s,{title:"Label items",children:e.jsx(b,{values:a,onPatch:n})}),v&&e.jsx(s,{title:"Number labels",children:e.jsx(p,{values:a,onPatch:n,count:10})})]}),o==="RATING_MATRIX"&&"unselectedStarOpacity"in a&&e.jsxs(e.Fragment,{children:[(h||m)&&e.jsxs(s,{title:`Rating — ${r.replace("RATING_","")}`,children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[h&&e.jsx(t,{label:"Emoji size (px)",value:a.emojiSize,onChange:l=>n({emojiSize:l}),min:16,max:40}),m&&e.jsx(u,{label:"Unselected opacity",value:Math.round(a.unselectedStarOpacity*100),onChange:l=>n({unselectedStarOpacity:l/100}),min:10,max:100})]}),e.jsx("p",{className:"text-xs text-slate-500",children:"Selected cell color and focus ring come from Theme → Question card."})]}),e.jsx(s,{title:"Label items",children:e.jsx(b,{values:a,onPatch:n})}),v&&e.jsx(s,{title:"Number labels",children:e.jsx(p,{values:a,onPatch:n,count:10})})]}),o==="SLIDER_MATRIX"&&"trackColor"in a&&e.jsxs(e.Fragment,{children:[e.jsx(s,{title:"Slider track",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(i,{label:"Track",value:a.trackColor,onChange:l=>n({trackColor:l})}),e.jsx(i,{label:"Thumb",value:a.thumbColor,onChange:l=>n({thumbColor:l})}),e.jsx(i,{label:"Tick",value:a.tickColor,onChange:l=>n({tickColor:l})}),e.jsx(t,{label:"Row label width (px)",value:a.rowLabelWidth,onChange:l=>n({rowLabelWidth:l}),min:120,max:280})]})}),e.jsx(s,{title:"Tick label items",children:e.jsx(b,{values:a,onPatch:n})}),e.jsx(s,{title:"Tick number labels",children:e.jsx(p,{values:a,onPatch:n,count:11})})]}),o==="FILE_UPLOAD"&&"dropzoneStyle"in a&&e.jsx(s,{title:"Dropzone",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(j,{label:"Dropzone border",value:a.dropzoneStyle,onChange:l=>n({dropzoneStyle:l}),options:[{value:"dashed",label:"Dashed"},{value:"solid",label:"Solid"}]}),e.jsx(i,{label:"Border color",value:a.borderColor??a.accentColor,onChange:l=>n({borderColor:l})}),e.jsx(i,{label:"Fill color",value:a.dropzoneFillColor,onChange:l=>n({dropzoneFillColor:l})}),e.jsx(t,{label:"Padding (px)",value:a.dropzonePadding,onChange:l=>n({dropzonePadding:l}),min:12,max:48})]})}),o==="HEATMAP"&&"pinColor"in a&&e.jsx(s,{title:"Heatmap pin",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(i,{label:"Pin color",value:a.pinColor,onChange:l=>n({pinColor:l})}),e.jsx(i,{label:"Pin border",value:a.pinBorderColor,onChange:l=>n({pinBorderColor:l})}),e.jsx(u,{label:"Pin size",value:a.pinSize,onChange:l=>n({pinSize:l}),min:8,max:32}),e.jsxs("p",{className:"text-xs text-slate-500 sm:col-span-2",children:["Click the heatmap image in the preview to place a pin and see styling update live. Pin preview position: ",Math.round(x.x*100),"%, ",Math.round(x.y*100),"%"]})]})}),o==="RANK_ORDER"&&"drag"in a&&e.jsx(s,{title:N?"Drag & drop":w?"Dropdown rank":"Rank order",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[N&&e.jsxs(e.Fragment,{children:[e.jsx(i,{label:"Item background",value:a.drag.itemBg,onChange:l=>n({drag:{...a.drag,itemBg:l}})}),e.jsx(i,{label:"Drag handle",value:a.drag.dragHandleColor,onChange:l=>n({drag:{...a.drag,dragHandleColor:l}})}),e.jsx(i,{label:"Rank badge",value:a.drag.rankBadgeColor,onChange:l=>n({drag:{...a.drag,rankBadgeColor:l}})})]}),w&&e.jsxs(e.Fragment,{children:[e.jsx(i,{label:"Item background",value:a.dropdown.itemBg,onChange:l=>n({dropdown:{...a.dropdown,itemBg:l}})}),e.jsx(i,{label:"Select border",value:a.dropdown.selectBorderColor,onChange:l=>n({dropdown:{...a.dropdown,selectBorderColor:l}})}),e.jsx(i,{label:"Rank badge",value:a.dropdown.rankBadgeColor,onChange:l=>n({dropdown:{...a.dropdown,rankBadgeColor:l}})})]})]})})]})}export{B as TypePanel};
|
|
1
|
+
import{u as g,j as e,T as f,S as j,R as u,N as t,C as i,a as M,M as L}from"./index-DtZhNwPS.js";import"./vendor-BwkXDkd3.js";function b({values:o,onPatch:r}){return e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(i,{label:"Label text color",value:o.columnLabelColor,onChange:a=>r({columnLabelColor:a})}),e.jsx(i,{label:"Label background",value:o.columnLabelBgColor,onChange:a=>r({columnLabelBgColor:a})})]})}function P({values:o,onPatch:r}){return e.jsxs("div",{className:"grid grid-cols-1 gap-3 sm:grid-cols-2",children:[e.jsxs("label",{className:"space-y-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Min hint label"}),e.jsx("input",{className:"w-full rounded-lg border border-white/10 bg-slate-950/50 px-3 py-2 text-sm text-white",value:o.hintMinText,onChange:a=>r({hintMinText:a.target.value})})]}),e.jsxs("label",{className:"space-y-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Max hint label"}),e.jsx("input",{className:"w-full rounded-lg border border-white/10 bg-slate-950/50 px-3 py-2 text-sm text-white",value:o.hintMaxText,onChange:a=>r({hintMaxText:a.target.value})})]}),e.jsx(i,{label:"Hint text color",value:o.hintLabelColor,onChange:a=>r({hintLabelColor:a})}),e.jsx(i,{label:"Hint label background",value:o.hintLabelBgColor,onChange:a=>r({hintLabelBgColor:a})})]})}function p({values:o,onPatch:r,count:a=11}){return e.jsxs("div",{className:"space-y-3",children:[e.jsx(j,{label:"Number label style",value:o.numberLabelMode,onChange:d=>r({numberLabelMode:d}),options:[{value:"traffic",label:"Traffic light (default)"},{value:"monochrome",label:"Monochrome (one color)"},{value:"individual",label:"Individual per number"}]}),o.numberLabelMode==="monochrome"&&e.jsx(i,{label:"Monochrome color",value:o.monochromeNumberColor,onChange:d=>r({monochromeNumberColor:d})}),o.numberLabelMode==="individual"&&e.jsx("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3",children:Array.from({length:a},(d,c)=>e.jsx(i,{label:`#${c}`,value:o.individualNumberColors[c]??"#9CA3AF",onChange:C=>{const x=[...o.individualNumberColors];x[c]=C,r({individualNumberColors:x})}},c))})]})}function s({title:o,children:r}){return e.jsxs("div",{className:"space-y-3 rounded-xl border border-white/5 bg-slate-950/20 p-4",children:[e.jsx("h4",{className:"text-xs font-semibold uppercase tracking-wider text-slate-400",children:o}),r]})}function B({type:o,activeFormat:r}){const a=g(l=>l.config.questionTypes[o]),d=g(l=>l.updateQuestionType),c=g(l=>l.previewMultiStatement),C=g(l=>l.setPreviewMultiStatement),x=g(l=>l.heatmapPreviewPin);if(!a)return e.jsx("p",{className:"text-sm text-slate-500",children:"No configuration available for this type."});const n=l=>d(o,l),S=L.includes(o),T=r.includes("star"),h=r.includes("emoji"),v=r.includes("numbered"),N=r.includes("drag"),w=r.includes("dropdown"),k=r.includes("radio"),m=h||T||v||k;return e.jsxs("div",{className:"space-y-4",children:[S&&e.jsx(f,{label:"Preview multiple statements",checked:c,onChange:C}),o==="MCQ"&&"optionGap"in a&&e.jsx(s,{title:"Option style",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(j,{label:"Option style",value:a.optionStyle??a.cardStyle??"outlined",onChange:l=>n({optionStyle:l}),options:[{value:"outlined",label:"Outlined"},{value:"filled",label:"Filled"},{value:"minimal",label:"Minimal"}]}),e.jsx(u,{label:"Option gap",value:a.optionGap,onChange:l=>n({optionGap:l}),min:0,max:32}),e.jsx(u,{label:"Border radius",value:a.borderRadius,onChange:l=>n({borderRadius:l}),min:0,max:24}),e.jsx(u,{label:"Option padding",value:a.optionPadding??12,onChange:l=>n({optionPadding:l}),min:4,max:24})]})}),o==="TEXTFIELD"&&"defaultPlaceholder"in a&&e.jsx(s,{title:"Text input",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsxs("label",{className:"space-y-1 sm:col-span-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-500",children:"Default placeholder"}),e.jsx("input",{className:"w-full rounded-lg border border-white/10 bg-slate-950/50 px-3 py-2 text-sm text-white",value:a.defaultPlaceholder,onChange:l=>n({defaultPlaceholder:l.target.value})})]}),e.jsx(t,{label:"Input radius (px)",value:a.inputRadius,onChange:l=>n({inputRadius:l}),min:0,max:24}),e.jsx(i,{label:"Border color",value:a.borderColor,onChange:l=>n({borderColor:l})}),e.jsx(i,{label:"Placeholder color",value:a.placeholderColor,onChange:l=>n({placeholderColor:l})})]})}),o==="NPS_SCALE"&&"buttonStyle"in a&&e.jsxs(e.Fragment,{children:[e.jsx(s,{title:"NPS buttons",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(j,{label:"Button style",value:a.buttonStyle,onChange:l=>n({buttonStyle:l}),options:[{value:"standard",label:"Radio"},{value:"numbered",label:"Numbered badges"},{value:"pill",label:"Pill"}]}),e.jsx(i,{label:"Selected fill",value:a.selectedFill,onChange:l=>n({selectedFill:l})}),e.jsx(i,{label:"Track bar",value:a.trackBarColor,onChange:l=>n({trackBarColor:l})}),e.jsx(i,{label:"Track highlight",value:a.trackHighlightColor,onChange:l=>n({trackHighlightColor:l})})]})}),e.jsx(s,{title:"Hint labels",children:e.jsx(P,{values:a,onPatch:n})}),e.jsx(s,{title:"Number labels",children:e.jsx(p,{values:a,onPatch:n})})]}),o==="CFM_MATRIX"&&"rowLabelWidth"in a&&e.jsxs(e.Fragment,{children:[e.jsx(s,{title:"Matrix layout",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(t,{label:"Row label width (px)",value:a.rowLabelWidth,onChange:l=>n({rowLabelWidth:l}),min:120,max:280}),e.jsx(t,{label:"Bipolar column width (%)",value:a.bipolarColumnWidthPercent,onChange:l=>n({bipolarColumnWidthPercent:l}),min:15,max:40})]})}),e.jsx(s,{title:"Label items",children:e.jsx(b,{values:a,onPatch:n})})]}),o==="CSAT_MATRIX"&&"emojiSize"in a&&e.jsxs(e.Fragment,{children:[(h||m)&&e.jsxs(s,{title:`${M.CSAT_MATRIX} — ${r.replace("CSAT_","")}`,children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[h&&e.jsx(t,{label:"Emoji size (px)",value:a.emojiSize,onChange:l=>n({emojiSize:l}),min:16,max:40}),m&&e.jsx(u,{label:"Unselected opacity",value:Math.round(a.unselectedOpacity*100),onChange:l=>n({unselectedOpacity:l/100}),min:10,max:100})]}),e.jsx("p",{className:"text-xs text-slate-500",children:"Selected cell color and focus ring come from Theme → Question card."})]}),e.jsx(s,{title:"Label items",children:e.jsx(b,{values:a,onPatch:n})}),v&&e.jsx(s,{title:"Number labels",children:e.jsx(p,{values:a,onPatch:n,count:10})})]}),o==="RATING_MATRIX"&&"unselectedStarOpacity"in a&&e.jsxs(e.Fragment,{children:[(h||m)&&e.jsxs(s,{title:`Rating — ${r.replace("RATING_","")}`,children:[e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[h&&e.jsx(t,{label:"Emoji size (px)",value:a.emojiSize,onChange:l=>n({emojiSize:l}),min:16,max:40}),m&&e.jsx(u,{label:"Unselected opacity",value:Math.round(a.unselectedStarOpacity*100),onChange:l=>n({unselectedStarOpacity:l/100}),min:10,max:100})]}),e.jsx("p",{className:"text-xs text-slate-500",children:"Selected cell color and focus ring come from Theme → Question card."})]}),e.jsx(s,{title:"Label items",children:e.jsx(b,{values:a,onPatch:n})}),v&&e.jsx(s,{title:"Number labels",children:e.jsx(p,{values:a,onPatch:n,count:10})})]}),o==="SLIDER_MATRIX"&&"trackColor"in a&&e.jsxs(e.Fragment,{children:[e.jsx(s,{title:"Slider track",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(i,{label:"Track",value:a.trackColor,onChange:l=>n({trackColor:l})}),e.jsx(i,{label:"Thumb",value:a.thumbColor,onChange:l=>n({thumbColor:l})}),e.jsx(i,{label:"Tick",value:a.tickColor,onChange:l=>n({tickColor:l})}),e.jsx(t,{label:"Row label width (px)",value:a.rowLabelWidth,onChange:l=>n({rowLabelWidth:l}),min:120,max:280})]})}),e.jsx(s,{title:"Tick label items",children:e.jsx(b,{values:a,onPatch:n})}),e.jsx(s,{title:"Tick number labels",children:e.jsx(p,{values:a,onPatch:n,count:11})})]}),o==="FILE_UPLOAD"&&"dropzoneStyle"in a&&e.jsx(s,{title:"Dropzone",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(j,{label:"Dropzone border",value:a.dropzoneStyle,onChange:l=>n({dropzoneStyle:l}),options:[{value:"dashed",label:"Dashed"},{value:"solid",label:"Solid"}]}),e.jsx(i,{label:"Border color",value:a.borderColor??a.accentColor,onChange:l=>n({borderColor:l})}),e.jsx(i,{label:"Fill color",value:a.dropzoneFillColor,onChange:l=>n({dropzoneFillColor:l})}),e.jsx(t,{label:"Padding (px)",value:a.dropzonePadding,onChange:l=>n({dropzonePadding:l}),min:12,max:48})]})}),o==="HEATMAP"&&"pinColor"in a&&e.jsx(s,{title:"Heatmap pin",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(i,{label:"Pin color",value:a.pinColor,onChange:l=>n({pinColor:l})}),e.jsx(i,{label:"Pin border",value:a.pinBorderColor,onChange:l=>n({pinBorderColor:l})}),e.jsx(u,{label:"Pin size",value:a.pinSize,onChange:l=>n({pinSize:l}),min:8,max:32}),e.jsxs("p",{className:"text-xs text-slate-500 sm:col-span-2",children:["Click the heatmap image in the preview to place a pin and see styling update live. Pin preview position: ",Math.round(x.x*100),"%, ",Math.round(x.y*100),"%"]})]})}),o==="RANK_ORDER"&&"drag"in a&&e.jsx(s,{title:N?"Drag & drop":w?"Dropdown rank":"Rank order",children:e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[N&&e.jsxs(e.Fragment,{children:[e.jsx(i,{label:"Item background",value:a.drag.itemBg,onChange:l=>n({drag:{...a.drag,itemBg:l}})}),e.jsx(i,{label:"Drag handle",value:a.drag.dragHandleColor,onChange:l=>n({drag:{...a.drag,dragHandleColor:l}})}),e.jsx(i,{label:"Rank badge",value:a.drag.rankBadgeColor,onChange:l=>n({drag:{...a.drag,rankBadgeColor:l}})})]}),w&&e.jsxs(e.Fragment,{children:[e.jsx(i,{label:"Item background",value:a.dropdown.itemBg,onChange:l=>n({dropdown:{...a.dropdown,itemBg:l}})}),e.jsx(i,{label:"Select border",value:a.dropdown.selectBorderColor,onChange:l=>n({dropdown:{...a.dropdown,selectBorderColor:l}})}),e.jsx(i,{label:"Rank badge",value:a.dropdown.rankBadgeColor,onChange:l=>n({dropdown:{...a.dropdown,rankBadgeColor:l}})})]})]})})]})}export{B as TypePanel};
|