@explorer02/cfm-survey-sdk 0.2.7 → 0.2.9

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 (44) hide show
  1. package/dist/cli/index.js +38 -41
  2. package/dist/cli/index.mjs +36 -39
  3. package/package.json +1 -1
  4. package/templates/docs/00-integration/agent-execution-flow.md +7 -9
  5. package/templates/docs/00-integration/agent-operating-contract.md +2 -1
  6. package/templates/docs/00-integration/component-checklist.md +1 -0
  7. package/templates/docs/00-integration/ui-customization-wizard.md +29 -7
  8. package/templates/docs/00-integration/wizard-chrome-contract.md +11 -1
  9. package/templates/docs/00-integration/wizard-config-handoff.md +11 -9
  10. package/templates/docs/00-integration/wizard-post-customize-build.md +8 -2
  11. package/templates/docs/00-integration/wizard-preview-build-guide.md +0 -2
  12. package/templates/docs/00-integration/wizard-question-type-styling.md +7 -6
  13. package/templates/docs/00-integration/wizard-troubleshooting.md +20 -4
  14. package/templates/docs/03-ui-specs/README.md +1 -1
  15. package/templates/docs/MANIFEST.json +0 -3
  16. package/templates/docs/index.md +4 -6
  17. package/templates/docs/templates/CsatMatrixScale.tsx +56 -53
  18. package/templates/docs/templates/CustomSliderTrack.tsx +17 -8
  19. package/templates/docs/templates/FileUploadScale.tsx +11 -3
  20. package/templates/docs/templates/Header.tsx +32 -48
  21. package/templates/docs/templates/HeatmapScale.tsx +7 -4
  22. package/templates/docs/templates/LikertMatrixScale.tsx +58 -43
  23. package/templates/docs/templates/MatrixDropdown.tsx +12 -11
  24. package/templates/docs/templates/Question.tsx +4 -23
  25. package/templates/docs/templates/RankOrderScale.tsx +46 -6
  26. package/templates/docs/templates/RatingScale.tsx +38 -0
  27. package/templates/docs/templates/SliderMatrixScale.tsx +4 -3
  28. package/templates/docs/templates/verify-agent-build.sh +17 -0
  29. package/templates/preview-harness/preview-bridge.inline.js +10 -0
  30. package/templates/preview-harness/previewPages.ts +5 -7
  31. package/templates/preview-harness/vite-app/src/QuestionPreview.tsx +11 -6
  32. package/templates/preview-harness/vite-app/src/fixtures/questions.ts +2 -10
  33. package/templates/preview-harness/vite-app/src/preview-live-overrides.css +11 -6
  34. package/templates/previewBridge.ts +13 -0
  35. package/templates/survey-theme.css +17 -17
  36. package/templates/wizard-dist/assets/{PreviewMock-tTMvwuEy.js → PreviewMock-CysRws9G.js} +1 -1
  37. package/templates/wizard-dist/assets/TypePanel-DWX1LL3q.js +1 -0
  38. package/templates/wizard-dist/assets/index-DIuc7AU2.js +34 -0
  39. package/templates/wizard-dist/assets/index-pCM8n0FT.css +1 -0
  40. package/templates/wizard-dist/index.html +2 -2
  41. package/templates/docs/00-integration/wizard-customization-catalog.md +0 -391
  42. package/templates/wizard-dist/assets/TypePanel-B9Ls7BSq.js +0 -1
  43. package/templates/wizard-dist/assets/index-CjkIlOUI.css +0 -1
  44. package/templates/wizard-dist/assets/index-CoCrnnxt.js +0 -34
@@ -6,6 +6,7 @@ import {
6
6
  scaleRadioDotStyle,
7
7
  scaleCellSelectedStyle,
8
8
  } from '@/lib/surveyUi/selectionStyles';
9
+ import { hintLabelStyle } from '@/lib/surveyUi/labelStyles';
9
10
  import { getAccentColor, npsValueFromOption, starValueFromOption } from './surveyUiScaleUtils';
10
11
  import { getEmojiForIndex } from './surveyUiIcons';
11
12
 
@@ -16,6 +17,10 @@ type RatingScaleProps = {
16
17
  onSelect: (value: AnswerValue) => void;
17
18
  variant?: 'nps' | 'star';
18
19
  buttonStyle?: 'standard' | 'numbered' | 'emoji';
20
+ minLabel?: string;
21
+ midLabel?: string;
22
+ maxLabel?: string;
23
+ midLabelIndex?: number;
19
24
  };
20
25
 
21
26
  function resolveBadgeColor(index: number, value: number): string {
@@ -44,6 +49,10 @@ export default function RatingScale({
44
49
  onSelect,
45
50
  variant = 'nps',
46
51
  buttonStyle = 'numbered',
52
+ minLabel,
53
+ midLabel,
54
+ maxLabel,
55
+ midLabelIndex,
47
56
  }: RatingScaleProps) {
48
57
  const resolvedOptions = options.map((option, index) => {
49
58
  const value =
@@ -63,9 +72,37 @@ export default function RatingScale({
63
72
  gap: 'var(--cfm-nps-cell-gap, 2px)',
64
73
  };
65
74
 
75
+ const hintRow = (minLabel || midLabel || maxLabel) ? (
76
+ <div className="relative mb-3 h-6 w-full text-xs font-semibold">
77
+ <span
78
+ className="absolute left-0 top-0 max-w-[30%] text-left leading-tight"
79
+ style={hintLabelStyle()}
80
+ dangerouslySetInnerHTML={{ __html: minLabel ?? '' }}
81
+ />
82
+ {midLabel && (
83
+ <span
84
+ className="absolute top-0 -translate-x-1/2 max-w-[40%] text-center leading-tight"
85
+ style={{
86
+ ...hintLabelStyle(),
87
+ left: `${midLabelIndex !== undefined && columnCount > 1
88
+ ? (midLabelIndex / (columnCount - 1)) * 100
89
+ : 50}%`,
90
+ }}
91
+ dangerouslySetInnerHTML={{ __html: midLabel }}
92
+ />
93
+ )}
94
+ <span
95
+ className="absolute right-0 top-0 max-w-[30%] text-right leading-tight"
96
+ style={hintLabelStyle()}
97
+ dangerouslySetInnerHTML={{ __html: maxLabel ?? '' }}
98
+ />
99
+ </div>
100
+ ) : null;
101
+
66
102
  if (buttonStyle === 'emoji') {
67
103
  return (
68
104
  <div role="radiogroup" className="w-full overflow-x-auto" data-cfm-nps-area>
105
+ {hintRow}
69
106
  <div className="min-w-0" style={gridStyle}>
70
107
  {resolvedOptions.map((option, index) => {
71
108
  const isSelected = selectedValue === option.value;
@@ -90,6 +127,7 @@ export default function RatingScale({
90
127
 
91
128
  return (
92
129
  <div role="radiogroup" className="w-full overflow-x-auto" data-cfm-nps-area>
130
+ {hintRow}
93
131
  <div className="mb-3 min-w-0" style={gridStyle}>
94
132
  {resolvedOptions.map((option, index) => {
95
133
  const isSelected = selectedValue === option.value;
@@ -7,6 +7,7 @@
7
7
 
8
8
  import React from 'react';
9
9
  import type { SliderMatrixQuestion, MatrixRowAnswers } from '@explorer02/cfm-survey-sdk';
10
+ import { sliderTickLabelStyle } from '@/lib/surveyUi/labelStyles';
10
11
  import { tickColorFromIndex } from './surveyUiScaleUtils';
11
12
  import { CustomSliderTrack } from './CustomSliderTrack';
12
13
 
@@ -97,7 +98,7 @@ export function SliderMatrixScale({ question, selectedValue = {}, onSelect }: Sl
97
98
  width: `${sliceWidth}%`, display: 'flex', justifyContent: 'center',
98
99
  }}>
99
100
  {sliderType === 'graphics' ? (
100
- <div style={{ wordBreak: 'break-word', textAlign: 'center', lineHeight: '1.2', fontWeight: 500, color: '#4b5563', fontSize: '13px' }}>
101
+ <div style={{ wordBreak: 'break-word', textAlign: 'center', lineHeight: '1.2', fontWeight: 500, fontSize: '13px', ...sliderTickLabelStyle() }}>
101
102
  {tv.label}
102
103
  </div>
103
104
  ) : (
@@ -121,7 +122,7 @@ export function SliderMatrixScale({ question, selectedValue = {}, onSelect }: Sl
121
122
  position: 'absolute', left: `${percentage}%`, transform: 'translateX(-50%)',
122
123
  width: `${sliceWidth}%`, display: 'flex', justifyContent: 'center',
123
124
  }}>
124
- <span style={{ wordBreak: 'break-word', textAlign: 'center', lineHeight: '1.2' }}>{m}</span>
125
+ <span style={{ wordBreak: 'break-word', textAlign: 'center', lineHeight: '1.2', ...sliderTickLabelStyle() }}>{m}</span>
125
126
  </div>
126
127
  );
127
128
  })
@@ -151,7 +152,7 @@ export function SliderMatrixScale({ question, selectedValue = {}, onSelect }: Sl
151
152
  return (
152
153
  <div key={row.id} style={{
153
154
  display: 'flex', width: '100%', alignItems: 'center',
154
- backgroundColor: '#f3f4f6', borderRadius: '12px', padding: '16px', boxSizing: 'border-box',
155
+ backgroundColor: 'var(--cfm-slider-row-band)', borderRadius: '12px', padding: '16px', boxSizing: 'border-box',
155
156
  }}>
156
157
  <div style={{ flex: '0 0 25%', paddingRight: '16px', fontSize: '15px', color: '#111827', wordWrap: 'break-word', display: 'flex', alignItems: 'center' }}>
157
158
  {row.statementText !== 'Question' && row.statementText !== '' ? (
@@ -102,6 +102,23 @@ if ! grep -q "layoutFlags" "$PREVIEW_BRIDGE"; then
102
102
  fi
103
103
  echo "OK: previewBridge.ts present with layoutFlags"
104
104
 
105
+ # Scale templates must consume wizard CSS vars (not only RatingScale)
106
+ SCALE_CFM_COUNT=0
107
+ for candidate in src/components/LikertMatrixScale.tsx components/LikertMatrixScale.tsx app/components/LikertMatrixScale.tsx; do
108
+ if [ -f "$candidate" ] && grep -q -- '--cfm-' "$candidate"; then SCALE_CFM_COUNT=1; break; fi
109
+ done
110
+ if [ "$SCALE_CFM_COUNT" -eq 0 ]; then
111
+ echo "WARN: LikertMatrixScale.tsx missing --cfm-* vars — copy from docs/templates"
112
+ fi
113
+
114
+ SCALE_CSAT_COUNT=0
115
+ for candidate in src/components/CsatMatrixScale.tsx components/CsatMatrixScale.tsx app/components/CsatMatrixScale.tsx; do
116
+ if [ -f "$candidate" ] && grep -q -- '--cfm-' "$candidate"; then SCALE_CSAT_COUNT=1; break; fi
117
+ done
118
+ if [ "$SCALE_CSAT_COUNT" -eq 0 ]; then
119
+ echo "WARN: CsatMatrixScale.tsx missing --cfm-* vars — copy from docs/templates"
120
+ fi
121
+
105
122
  REQUIRED_TYPES=(MCQ TEXTFIELD NPS_SCALE CFM_MATRIX CSAT_MATRIX RATING_MATRIX SLIDER_MATRIX FILE_UPLOAD TEXT_AND_MEDIA HEATMAP RANK_ORDER)
106
123
  QUESTION_FILE=""
107
124
  for candidate in src/components/Question.tsx components/Question.tsx app/components/Question.tsx; do
@@ -176,6 +176,16 @@
176
176
  el.setAttribute('placeholder', patch.previewState.textfieldPlaceholder || '');
177
177
  });
178
178
  }
179
+ if (patch.previewState && patch.previewState.hintMinText !== undefined) {
180
+ document.querySelectorAll('[data-cfm-hint-min]').forEach(function (el) {
181
+ el.textContent = patch.previewState.hintMinText || '';
182
+ });
183
+ }
184
+ if (patch.previewState && patch.previewState.hintMaxText !== undefined) {
185
+ document.querySelectorAll('[data-cfm-hint-max]').forEach(function (el) {
186
+ el.textContent = patch.previewState.hintMaxText || '';
187
+ });
188
+ }
179
189
  }
180
190
 
181
191
  function handleMessage(event) {
@@ -3,8 +3,9 @@ export type PreviewPageDef = { key: string; title: string; body: string };
3
3
 
4
4
  const sharedStyles = `
5
5
  .cfm-header { height:var(--cfm-header-height); background:var(--cfm-header-bg); border-bottom:1px solid var(--cfm-header-border); display:flex; align-items:center; padding:0 var(--cfm-header-padding-x); box-shadow:0 2px 8px rgba(0,0,0,0.06); }
6
- .cfm-header-logo { width:var(--cfm-header-logo-width); height:var(--cfm-header-logo-height); object-fit:contain; padding:var(--cfm-header-logo-padding); background:var(--cfm-primary); }
7
- .cfm-header-company { font-size:var(--cfm-header-company-size); font-weight:var(--cfm-header-company-weight); color:var(--cfm-header-company-color); margin-left:16px; }
6
+ .cfm-header-brand { display:flex; align-items:center; gap:var(--cfm-header-brand-gap,16px); }
7
+ .cfm-header-logo { width:var(--cfm-header-logo-width); height:var(--cfm-header-logo-height); object-fit:contain; padding:var(--cfm-header-logo-padding); background:var(--cfm-header-logo-bg,transparent); }
8
+ .cfm-header-company { font-size:var(--cfm-header-company-size); font-weight:var(--cfm-header-company-weight); color:var(--cfm-header-company-color); }
8
9
  .cfm-footer { background:var(--cfm-footer-bg); color:var(--cfm-footer-text); padding:var(--cfm-footer-padding-y) var(--cfm-footer-padding-x); display:flex; flex-wrap:wrap; gap:16px; justify-content:space-between; align-items:flex-end; }
9
10
  .cfm-footer-links { display:flex; gap:24px; flex-wrap:wrap; }
10
11
  .cfm-footer-links a { color:var(--cfm-footer-link); text-decoration:none; font-size:12px; }
@@ -28,7 +29,7 @@ const sharedStyles = `
28
29
  .cfm-slider-track { height:8px; background:var(--cfm-slider-track); border-radius:4px; position:relative; margin:24px 0; }
29
30
  .cfm-slider-thumb { width:20px; height:20px; background:var(--cfm-slider-thumb); border-radius:50%; position:absolute; top:-6px; left:60%; }
30
31
  .cfm-tick { width:var(--cfm-slider-tick-size); height:var(--cfm-slider-tick-size); background:var(--cfm-slider-tick); border-radius:4px; font-size:11px; display:flex; align-items:center; justify-content:center; color:white; }
31
- .cfm-dropzone { border:2px dashed var(--cfm-upload-accent); border-radius:var(--cfm-border-radius); padding:var(--cfm-upload-padding); text-align:center; color:var(--cfm-text); }
32
+ .cfm-dropzone { border:2px dashed var(--cfm-upload-border-color); border-radius:var(--cfm-border-radius); padding:var(--cfm-upload-padding); background:var(--cfm-upload-fill); text-align:center; color:var(--cfm-text); }
32
33
  .cfm-input { width:100%; height:var(--cfm-input-height); border:1px solid var(--cfm-input-border); border-radius:var(--cfm-input-radius); padding:0 var(--cfm-input-padding); font-family:inherit; }
33
34
  .cfm-input:focus { outline:2px solid var(--cfm-input-focus-ring); }
34
35
  .cfm-rank-item { background:var(--cfm-rank-item-bg); padding:var(--cfm-rank-item-padding); margin-bottom:var(--cfm-rank-item-gap); border-radius:var(--cfm-border-radius); display:flex; align-items:center; gap:12px; }
@@ -59,10 +60,7 @@ export const PREVIEW_PAGE_DEFS: PreviewPageDef[] = [
59
60
  {
60
61
  key: 'header',
61
62
  title: 'Header',
62
- body: `<header class="cfm-header">
63
- <img data-cfm-logo class="cfm-header-logo" src="" alt="Logo" style="display:none" />
64
- <span data-cfm-company class="cfm-header-company">Company Name</span>
65
- </header>`,
63
+ body: `<header class="cfm-header"><div class="cfm-header-brand"><img data-cfm-logo class="cfm-header-logo" src="" alt="Logo" style="display:none" /><span data-cfm-company class="cfm-header-company"></span></div></header>`,
66
64
  },
67
65
  {
68
66
  key: 'footer',
@@ -65,12 +65,17 @@ function QuestionPreviewInner({ question, initialValue }: QuestionPreviewProps)
65
65
  }
66
66
  }
67
67
 
68
- if (previewState.multiStatement && 'statementRows' in q && q.statementRows.length === 1) {
69
- const extra = {
70
- id: 'r2',
71
- statementText: 'Second statement row',
72
- };
73
- q = { ...q, statementRows: [...q.statementRows, extra] } as typeof q;
68
+ const matrixTypes = new Set(['CFM_MATRIX', 'CSAT_MATRIX', 'RATING_MATRIX', 'SLIDER_MATRIX']);
69
+ if ('statementRows' in q && matrixTypes.has(q.type)) {
70
+ const rows = q.statementRows ?? [];
71
+ if (previewState.multiStatement) {
72
+ if (rows.length === 1) {
73
+ const extra = { id: 'r2', statementText: 'Second statement row' };
74
+ q = { ...q, statementRows: [...rows, extra] } as typeof q;
75
+ }
76
+ } else if (rows.length > 1) {
77
+ q = { ...q, statementRows: rows.slice(0, 1) } as typeof q;
78
+ }
74
79
  }
75
80
 
76
81
  if (previewState.rankVariant === 'drag' && q.type === 'RANK_ORDER') {
@@ -11,11 +11,6 @@ const base = (partial: Partial<SurveyQuestion> & { type: SurveyQuestion['type']
11
11
  ...partial,
12
12
  }) as SurveyQuestion;
13
13
 
14
- const MATRIX_ROWS_MULTI = [
15
- { id: 'r1', statementText: 'The product is easy to use' },
16
- { id: 'r2', statementText: 'Support was helpful' },
17
- ];
18
-
19
14
  export const FIXTURE_INTRO: SpecialPage = {
20
15
  id: 'preview-intro',
21
16
  header: 'Welcome to our survey',
@@ -99,7 +94,7 @@ export const FIXTURE_TEXT_LONG = base({
99
94
 
100
95
  export const FIXTURE_CFM_LIKERT = base({
101
96
  type: 'CFM_MATRIX',
102
- statementRows: MATRIX_ROWS_MULTI,
97
+ statementRows: [{ id: 'r1', statementText: 'The product is easy to use' }],
103
98
  scaleColumns: [
104
99
  { id: 'c1', label: 'Strongly disagree' },
105
100
  { id: 'c2', label: 'Disagree' },
@@ -232,10 +227,7 @@ export const FIXTURE_RATING_SLIDER = base({
232
227
 
233
228
  export const FIXTURE_SLIDER = base({
234
229
  type: 'SLIDER_MATRIX',
235
- statementRows: [
236
- { id: 'r1', statementText: 'Ease of use', min: 0, max: 10, step: 1 },
237
- { id: 'r2', statementText: 'Speed', min: 0, max: 10, step: 1 },
238
- ],
230
+ statementRows: [{ id: 'r1', statementText: 'Ease of use', min: 0, max: 10, step: 1 }],
239
231
  scaleAnchorLabels: ['Not at all', 'Extremely'],
240
232
  ticks: {
241
233
  count: 11,
@@ -75,15 +75,20 @@ html.cfm-live-edit .max-w-4xl {
75
75
  max-width: var(--cfm-max-width, 48rem) !important;
76
76
  }
77
77
 
78
- html.cfm-live-edit .cfm-header-inner {
79
- flex-direction: var(--cfm-header-flex-direction, column) !important;
80
- justify-content: var(--cfm-header-justify, flex-start) !important;
81
- align-items: var(--cfm-header-brand-align, flex-start) !important;
78
+ html.cfm-live-edit .cfm-header-brand {
79
+ display: flex !important;
80
+ align-items: center !important;
81
+ gap: var(--cfm-header-brand-gap, 16px) !important;
82
+ }
83
+
84
+ html.cfm-live-edit [data-cfm-logo] {
85
+ background: var(--cfm-header-logo-bg, transparent) !important;
86
+ object-fit: contain !important;
82
87
  }
83
88
 
84
89
  html.cfm-live-edit [data-cfm-company] {
85
- margin-top: var(--cfm-header-company-margin-top, 8px) !important;
86
- margin-left: var(--cfm-header-company-margin-left, 0) !important;
90
+ margin-top: 0 !important;
91
+ margin-left: 0 !important;
87
92
  }
88
93
 
89
94
  html.cfm-live-edit .cfm-footer-inner {
@@ -204,6 +204,19 @@ function applyContentPatch(patch: ContentPatch): void {
204
204
  el.setAttribute('placeholder', placeholder);
205
205
  });
206
206
  }
207
+
208
+ const hintMin = patch.previewState?.hintMinText;
209
+ if (typeof hintMin === 'string') {
210
+ document.querySelectorAll('[data-cfm-hint-min]').forEach((el) => {
211
+ el.textContent = hintMin;
212
+ });
213
+ }
214
+ const hintMax = patch.previewState?.hintMaxText;
215
+ if (typeof hintMax === 'string') {
216
+ document.querySelectorAll('[data-cfm-hint-max]').forEach((el) => {
217
+ el.textContent = hintMax;
218
+ });
219
+ }
207
220
  }
208
221
 
209
222
  function setLiveEditMode(on: boolean): void {
@@ -18,7 +18,8 @@
18
18
  --cfm-header-height: 120px;
19
19
  --cfm-header-logo-width: 120px;
20
20
  --cfm-header-logo-height: 120px;
21
- --cfm-header-logo-padding: 10px;
21
+ --cfm-header-logo-padding: 0px;
22
+ --cfm-header-logo-bg: transparent;
22
23
  --cfm-header-bg: #ffffff;
23
24
  --cfm-header-company-color: #1a1f36;
24
25
  --cfm-header-company-size: 18px;
@@ -181,8 +182,7 @@ body {
181
182
  }
182
183
 
183
184
  .cfm-header-inner {
184
- display: grid;
185
- grid-template-columns: 1fr auto 1fr;
185
+ display: flex;
186
186
  align-items: center;
187
187
  gap: var(--cfm-header-brand-gap, 16px);
188
188
  padding-left: var(--cfm-header-padding-x);
@@ -191,27 +191,27 @@ body {
191
191
  padding-bottom: 12px;
192
192
  min-height: var(--cfm-header-height);
193
193
  box-sizing: border-box;
194
+ width: 100%;
194
195
  }
195
196
 
196
- .cfm-header-logo-slot {
197
- grid-column: var(--cfm-header-logo-col, 1);
198
- grid-row: 1;
199
- justify-self: var(--cfm-header-logo-justify, start);
200
- width: var(--cfm-header-logo-width);
201
- height: var(--cfm-header-logo-height);
197
+ .cfm-header-brand {
198
+ display: flex;
199
+ align-items: center;
200
+ gap: var(--cfm-header-brand-gap, 16px);
201
+ min-width: 0;
202
202
  }
203
203
 
204
- .cfm-header-company-slot {
205
- grid-column: var(--cfm-header-company-col, 1);
206
- grid-row: 1;
207
- justify-self: var(--cfm-header-company-justify, start);
208
- align-self: center;
204
+ .cfm-header-brand [data-cfm-logo],
205
+ .cfm-header-logo-slot [data-cfm-logo] {
206
+ background: var(--cfm-header-logo-bg, transparent);
207
+ object-fit: contain;
208
+ }
209
+
210
+ .cfm-header-company-slot,
211
+ [data-cfm-company] {
209
212
  color: var(--cfm-header-company-color);
210
213
  font-size: var(--cfm-header-company-size);
211
214
  font-weight: var(--cfm-header-company-weight);
212
- margin-top: var(--cfm-header-company-margin-top, 0);
213
- margin-left: var(--cfm-header-company-margin-left, 0);
214
- margin-right: var(--cfm-header-company-margin-right, 0);
215
215
  line-height: 1.2;
216
216
  }
217
217
 
@@ -1 +1 @@
1
- import{u as x,j as e}from"./index-CoCrnnxt.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
+ import{u as x,j as e}from"./index-DIuc7AU2.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};
@@ -0,0 +1 @@
1
+ import{u as m,j as e,T as M,S as j,R as u,N as t,C as r,a as L,M as P}from"./index-DIuc7AU2.js";import"./vendor-BwkXDkd3.js";function b({values:o,onPatch:i}){return e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(r,{label:"Label text color",value:o.columnLabelColor,onChange:a=>i({columnLabelColor:a})}),e.jsx(r,{label:"Label background",value:o.columnLabelBgColor,onChange:a=>i({columnLabelBgColor:a})})]})}function k({values:o,onPatch:i}){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=>i({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=>i({hintMaxText:a.target.value})})]}),e.jsx(r,{label:"Hint text color",value:o.hintLabelColor,onChange:a=>i({hintLabelColor:a})}),e.jsx(r,{label:"Hint label background",value:o.hintLabelBgColor,onChange:a=>i({hintLabelBgColor:a})})]})}function p({values:o,onPatch:i,count:a=11}){return e.jsxs("div",{className:"space-y-3",children:[e.jsx(j,{label:"Number label style",value:o.numberLabelMode,onChange:d=>i({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(r,{label:"Monochrome color",value:o.monochromeNumberColor,onChange:d=>i({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(r,{label:`#${c}`,value:o.individualNumberColors[c]??"#9CA3AF",onChange:C=>{const x=[...o.individualNumberColors];x[c]=C,i({individualNumberColors:x})}},c))})]})}function s({title:o,children:i}){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}),i]})}function B({type:o,activeFormat:i}){const a=m(l=>l.config.questionTypes[o]),d=m(l=>l.updateQuestionType),c=m(l=>l.previewMultiStatement),C=m(l=>l.setPreviewMultiStatement),x=m(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=P.includes(o),T=i.includes("star"),h=i.includes("emoji"),v=i.includes("numbered"),N=i.includes("drag"),w=i.includes("dropdown"),f=i.includes("radio"),g=h||T||v||f;return e.jsxs("div",{className:"space-y-4",children:[S&&e.jsx(M,{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(r,{label:"Border color",value:a.borderColor,onChange:l=>n({borderColor:l})}),e.jsx(r,{label:"Placeholder color",value:a.placeholderColor,onChange:l=>n({placeholderColor:l})})]})}),o==="NPS_SCALE"&&"buttonStyle"in a&&e.jsxs(e.Fragment,{children:[e.jsxs(s,{title:"NPS buttons",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("p",{className:"text-xs text-slate-500",children:"Selected cell and focus ring come from Theme → Question card."})]}),e.jsx(s,{title:"Hint labels",children:e.jsx(k,{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||g)&&e.jsxs(s,{title:`${L.CSAT_MATRIX} — ${i.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}),g&&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||g)&&e.jsxs(s,{title:`Rating — ${i.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}),g&&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(r,{label:"Track",value:a.trackColor,onChange:l=>n({trackColor:l})}),e.jsx(r,{label:"Thumb",value:a.thumbColor,onChange:l=>n({thumbColor:l})}),e.jsx(r,{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(r,{label:"Border color",value:a.borderColor??a.accentColor,onChange:l=>n({borderColor:l})}),e.jsx(r,{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(r,{label:"Pin color",value:a.pinColor,onChange:l=>n({pinColor:l})}),e.jsx(r,{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(r,{label:"Item background",value:a.drag.itemBg,onChange:l=>n({drag:{...a.drag,itemBg:l}})}),e.jsx(r,{label:"Drag handle",value:a.drag.dragHandleColor,onChange:l=>n({drag:{...a.drag,dragHandleColor:l}})}),e.jsx(r,{label:"Rank badge",value:a.drag.rankBadgeColor,onChange:l=>n({drag:{...a.drag,rankBadgeColor:l}})})]}),w&&e.jsxs(e.Fragment,{children:[e.jsx(r,{label:"Item background",value:a.dropdown.itemBg,onChange:l=>n({dropdown:{...a.dropdown,itemBg:l}})}),e.jsx(r,{label:"Select border",value:a.dropdown.selectBorderColor,onChange:l=>n({dropdown:{...a.dropdown,selectBorderColor:l}})}),e.jsx(r,{label:"Rank badge",value:a.dropdown.rankBadgeColor,onChange:l=>n({dropdown:{...a.dropdown,rankBadgeColor:l}})})]})]})})]})}export{B as TypePanel};