@sensefolks/fastpoll 0.1.0
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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
- package/dist/cjs/index-CC5IS5t8.js +1437 -0
- package/dist/cjs/index-CC5IS5t8.js.map +1 -0
- package/dist/cjs/index-D8TNlmQq.js +201 -0
- package/dist/cjs/index-D8TNlmQq.js.map +1 -0
- package/dist/cjs/index.cjs.js +11 -0
- package/dist/cjs/index.cjs.js.map +1 -0
- package/dist/cjs/loader.cjs.js +16 -0
- package/dist/cjs/loader.cjs.js.map +1 -0
- package/dist/cjs/sf-fastpoll.cjs.entry.js +395 -0
- package/dist/cjs/sf-fastpoll.cjs.entry.js.map +1 -0
- package/dist/cjs/sf-fastpoll.cjs.js +28 -0
- package/dist/cjs/sf-fastpoll.cjs.js.map +1 -0
- package/dist/cjs/sf-fastpoll.entry.cjs.js.map +1 -0
- package/dist/collection/collection-manifest.json +12 -0
- package/dist/collection/components/sf-fastpoll/sf-fastpoll.css +76 -0
- package/dist/collection/components/sf-fastpoll/sf-fastpoll.js +454 -0
- package/dist/collection/components/sf-fastpoll/sf-fastpoll.js.map +1 -0
- package/dist/collection/index.js +11 -0
- package/dist/collection/index.js.map +1 -0
- package/dist/collection/utils/utils.js +189 -0
- package/dist/collection/utils/utils.js.map +1 -0
- package/dist/components/index.d.ts +33 -0
- package/dist/components/index.js +1427 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/sf-fastpoll.d.ts +11 -0
- package/dist/components/sf-fastpoll.js +425 -0
- package/dist/components/sf-fastpoll.js.map +1 -0
- package/dist/esm/app-globals-DQuL1Twl.js +6 -0
- package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm/index-CfdIRf0W.js +193 -0
- package/dist/esm/index-CfdIRf0W.js.map +1 -0
- package/dist/esm/index-XYfqntZe.js +1428 -0
- package/dist/esm/index-XYfqntZe.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/loader.js +14 -0
- package/dist/esm/loader.js.map +1 -0
- package/dist/esm/polyfills/core-js.js +11 -0
- package/dist/esm/polyfills/dom.js +79 -0
- package/dist/esm/polyfills/es5-html-element.js +1 -0
- package/dist/esm/polyfills/index.js +34 -0
- package/dist/esm/polyfills/system.js +6 -0
- package/dist/esm/sf-fastpoll.entry.js +393 -0
- package/dist/esm/sf-fastpoll.entry.js.map +1 -0
- package/dist/esm/sf-fastpoll.js +24 -0
- package/dist/esm/sf-fastpoll.js.map +1 -0
- package/dist/esm-es5/app-globals-DQuL1Twl.js +2 -0
- package/dist/esm-es5/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm-es5/index-CfdIRf0W.js +2 -0
- package/dist/esm-es5/index-CfdIRf0W.js.map +1 -0
- package/dist/esm-es5/index-XYfqntZe.js +3 -0
- package/dist/esm-es5/index-XYfqntZe.js.map +1 -0
- package/dist/esm-es5/index.js +2 -0
- package/dist/esm-es5/index.js.map +1 -0
- package/dist/esm-es5/loader.js +2 -0
- package/dist/esm-es5/loader.js.map +1 -0
- package/dist/esm-es5/sf-fastpoll.entry.js +2 -0
- package/dist/esm-es5/sf-fastpoll.entry.js.map +1 -0
- package/dist/esm-es5/sf-fastpoll.js +2 -0
- package/dist/esm-es5/sf-fastpoll.js.map +1 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/sf-fastpoll/index.esm.js +2 -0
- package/dist/sf-fastpoll/index.esm.js.map +1 -0
- package/dist/sf-fastpoll/loader.esm.js.map +1 -0
- package/dist/sf-fastpoll/p-1f6dca2a.system.entry.js +2 -0
- package/dist/sf-fastpoll/p-1f6dca2a.system.entry.js.map +1 -0
- package/dist/sf-fastpoll/p-4648bca3.entry.js +2 -0
- package/dist/sf-fastpoll/p-4648bca3.entry.js.map +1 -0
- package/dist/sf-fastpoll/p-BbPAtVJG.system.js +2 -0
- package/dist/sf-fastpoll/p-BbPAtVJG.system.js.map +1 -0
- package/dist/sf-fastpoll/p-C7EMppj8.system.js.map +1 -0
- package/dist/sf-fastpoll/p-C9ESvisV.system.js +3 -0
- package/dist/sf-fastpoll/p-C9ESvisV.system.js.map +1 -0
- package/dist/sf-fastpoll/p-CfdIRf0W.js +2 -0
- package/dist/sf-fastpoll/p-CfdIRf0W.js.map +1 -0
- package/dist/sf-fastpoll/p-CpmSDeqe.system.js +2 -0
- package/dist/sf-fastpoll/p-CpmSDeqe.system.js.map +1 -0
- package/dist/sf-fastpoll/p-DQuL1Twl.js +2 -0
- package/dist/sf-fastpoll/p-DQuL1Twl.js.map +1 -0
- package/dist/sf-fastpoll/p-JC66e5NR.system.js.map +1 -0
- package/dist/sf-fastpoll/p-S-cJYJS7.system.js +2 -0
- package/dist/sf-fastpoll/p-S-cJYJS7.system.js.map +1 -0
- package/dist/sf-fastpoll/p-XYfqntZe.js +3 -0
- package/dist/sf-fastpoll/p-XYfqntZe.js.map +1 -0
- package/dist/sf-fastpoll/p-zRZYYxiz.system.js +2 -0
- package/dist/sf-fastpoll/p-zRZYYxiz.system.js.map +1 -0
- package/dist/sf-fastpoll/sf-fastpoll.entry.esm.js.map +1 -0
- package/dist/sf-fastpoll/sf-fastpoll.esm.js +2 -0
- package/dist/sf-fastpoll/sf-fastpoll.esm.js.map +1 -0
- package/dist/sf-fastpoll/sf-fastpoll.js +127 -0
- package/dist/types/components/sf-fastpoll/sf-fastpoll.d.ts +77 -0
- package/dist/types/components.d.ts +47 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/stencil-public-runtime.d.ts +1709 -0
- package/dist/types/utils/utils.d.ts +86 -0
- package/loader/cdn.js +2 -0
- package/loader/index.cjs.js +2 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +2 -0
- package/loader/index.js +3 -0
- package/package.json +86 -0
- package/readme.md +239 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import { p as proxyCustomElement, H, isValidKey, E as Env, g as getFieldConfig, s as sanitizeInput, a as addToCommaSeparatedList, r as removeFromCommaSeparatedList, b as sanitizeByType, h, c as Host } from './index.js';
|
|
2
|
+
|
|
3
|
+
const sfFastpollCss = ":host{display:block}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0}input:focus,select:focus,button:focus{outline:2px solid #005fcc;outline-offset:2px}[aria-invalid='true']{border-color:#d32f2f}[part='error-message']{color:#d32f2f;font-size:0.875rem;margin-top:0.25rem}[part='choice-option']{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;margin:0.5rem 0;cursor:pointer}[part='choice-option']:hover{background-color:rgba(0, 95, 204, 0.1)}@media (prefers-contrast: high){input:focus,select:focus,button:focus{outline:3px solid}[part='error-message']{background-color:#d32f2f;color:white;padding:0.25rem}[part='choice-option']:hover{background-color:highlight;color:highlighttext}}@media (prefers-reduced-motion: reduce){*{-webkit-animation-duration:0.01ms !important;animation-duration:0.01ms !important;-webkit-animation-iteration-count:1 !important;animation-iteration-count:1 !important;-webkit-transition-duration:0.01ms !important;transition-duration:0.01ms !important}}";
|
|
4
|
+
|
|
5
|
+
const SURVEY_API_ENDPOINT = Env.SURVEY_API_ENDPOINT;
|
|
6
|
+
const RESPONSE_API_ENDPOINT = Env.RESPONSE_API_ENDPOINT;
|
|
7
|
+
var SurveyStep;
|
|
8
|
+
(function (SurveyStep) {
|
|
9
|
+
SurveyStep[SurveyStep["POLL"] = 0] = "POLL";
|
|
10
|
+
SurveyStep[SurveyStep["FOLLOW_UP"] = 1] = "FOLLOW_UP";
|
|
11
|
+
SurveyStep[SurveyStep["RESPONDENT_DETAILS"] = 2] = "RESPONDENT_DETAILS";
|
|
12
|
+
SurveyStep[SurveyStep["COMPLETION"] = 3] = "COMPLETION";
|
|
13
|
+
})(SurveyStep || (SurveyStep = {}));
|
|
14
|
+
const SfFastpoll$1 = /*@__PURE__*/ proxyCustomElement(class SfFastpoll extends H {
|
|
15
|
+
constructor() {
|
|
16
|
+
super();
|
|
17
|
+
this.__registerHost();
|
|
18
|
+
this.__attachShadow();
|
|
19
|
+
this.completionMessage = 'Thank you for your response!';
|
|
20
|
+
this.config = null;
|
|
21
|
+
this.respondentDetails = [];
|
|
22
|
+
this.loading = false;
|
|
23
|
+
this.error = null;
|
|
24
|
+
this.currentStep = SurveyStep.POLL;
|
|
25
|
+
this.selectedChoices = [];
|
|
26
|
+
this.selectedFollowUpChoices = [];
|
|
27
|
+
this.userRespondentDetails = {};
|
|
28
|
+
this.submitted = false;
|
|
29
|
+
this.announceMessage = '';
|
|
30
|
+
this.formErrors = {};
|
|
31
|
+
this.surveyStartTime = 0;
|
|
32
|
+
}
|
|
33
|
+
componentWillLoad() {
|
|
34
|
+
if (isValidKey(this.surveyKey)) {
|
|
35
|
+
return this.fetchSurveyData();
|
|
36
|
+
}
|
|
37
|
+
return Promise.resolve();
|
|
38
|
+
}
|
|
39
|
+
async fetchSurveyData() {
|
|
40
|
+
this.loading = true;
|
|
41
|
+
this.error = null;
|
|
42
|
+
this.surveyStartTime = Date.now();
|
|
43
|
+
try {
|
|
44
|
+
const response = await fetch(`${SURVEY_API_ENDPOINT}/${this.surveyKey}`);
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
if (!data.success) {
|
|
47
|
+
throw new Error(data.message);
|
|
48
|
+
}
|
|
49
|
+
this.config = data.payload.config;
|
|
50
|
+
this.respondentDetails = data.payload.respondentDetails || [];
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
this.error = error instanceof Error ? error.message : String(error);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
this.loading = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async retryOperation() {
|
|
60
|
+
if (this.config) {
|
|
61
|
+
// If we have config, retry submission
|
|
62
|
+
await this.submitResponse();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Otherwise, retry fetching survey data
|
|
66
|
+
await this.fetchSurveyData();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async submitResponse() {
|
|
70
|
+
if (!this.config || this.submitted) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.loading = true;
|
|
74
|
+
this.error = null;
|
|
75
|
+
try {
|
|
76
|
+
const completionTimeSeconds = this.surveyStartTime > 0 ? Math.round((Date.now() - this.surveyStartTime) / 1000) : 0;
|
|
77
|
+
const userAgentInfo = this.getUserAgentInfo();
|
|
78
|
+
const submissionData = {
|
|
79
|
+
surveyPublicKey: this.surveyKey,
|
|
80
|
+
responseData: {
|
|
81
|
+
selectedChoices: this.selectedChoices,
|
|
82
|
+
selectedFollowUpChoices: this.selectedFollowUpChoices,
|
|
83
|
+
},
|
|
84
|
+
respondentDetails: this.userRespondentDetails,
|
|
85
|
+
userAgent: userAgentInfo,
|
|
86
|
+
completionTime: completionTimeSeconds,
|
|
87
|
+
surveyType: 'fastPoll',
|
|
88
|
+
};
|
|
89
|
+
const response = await fetch(`${RESPONSE_API_ENDPOINT}`, {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
headers: {
|
|
92
|
+
'Content-Type': 'application/json',
|
|
93
|
+
},
|
|
94
|
+
body: JSON.stringify(submissionData),
|
|
95
|
+
});
|
|
96
|
+
const result = await response.json();
|
|
97
|
+
if (!result.success) {
|
|
98
|
+
throw new Error(result.message);
|
|
99
|
+
}
|
|
100
|
+
this.submitted = true;
|
|
101
|
+
this.currentStep = SurveyStep.COMPLETION;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
this.error = error instanceof Error ? error.message : String(error);
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
this.loading = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
getUserAgentInfo() {
|
|
111
|
+
// Use modern navigator.userAgentData when available, fallback to userAgent parsing
|
|
112
|
+
const getPlatform = () => {
|
|
113
|
+
var _a;
|
|
114
|
+
if ('userAgentData' in navigator && ((_a = navigator.userAgentData) === null || _a === void 0 ? void 0 : _a.platform)) {
|
|
115
|
+
return navigator.userAgentData.platform;
|
|
116
|
+
}
|
|
117
|
+
// Fallback: extract platform info from userAgent
|
|
118
|
+
const ua = navigator.userAgent;
|
|
119
|
+
if (ua.includes('Win'))
|
|
120
|
+
return 'Windows';
|
|
121
|
+
if (ua.includes('Mac'))
|
|
122
|
+
return 'macOS';
|
|
123
|
+
if (ua.includes('Linux'))
|
|
124
|
+
return 'Linux';
|
|
125
|
+
if (ua.includes('Android'))
|
|
126
|
+
return 'Android';
|
|
127
|
+
if (ua.includes('iOS'))
|
|
128
|
+
return 'iOS';
|
|
129
|
+
return 'Unknown';
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
userAgent: navigator.userAgent,
|
|
133
|
+
language: navigator.language,
|
|
134
|
+
platform: getPlatform(),
|
|
135
|
+
cookieEnabled: navigator.cookieEnabled,
|
|
136
|
+
onLine: navigator.onLine,
|
|
137
|
+
screenResolution: `${screen.width}x${screen.height}`,
|
|
138
|
+
colorDepth: screen.colorDepth,
|
|
139
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
140
|
+
timestamp: new Date().toISOString(),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
nextStep() {
|
|
144
|
+
if (!this.validateForm()) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (this.currentStep === SurveyStep.POLL) {
|
|
148
|
+
if (this.hasFollowUpStep()) {
|
|
149
|
+
this.currentStep = SurveyStep.FOLLOW_UP;
|
|
150
|
+
this.announceToScreenReader('Moving to follow-up question');
|
|
151
|
+
}
|
|
152
|
+
else if (this.hasRespondentDetailsStep()) {
|
|
153
|
+
this.currentStep = SurveyStep.RESPONDENT_DETAILS;
|
|
154
|
+
this.announceToScreenReader('Moving to respondent details');
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
this.announceToScreenReader('Submitting poll...');
|
|
158
|
+
this.submitResponse();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else if (this.currentStep === SurveyStep.FOLLOW_UP) {
|
|
162
|
+
if (this.hasRespondentDetailsStep()) {
|
|
163
|
+
this.currentStep = SurveyStep.RESPONDENT_DETAILS;
|
|
164
|
+
this.announceToScreenReader('Moving to respondent details');
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.announceToScreenReader('Submitting poll...');
|
|
168
|
+
this.submitResponse();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (this.currentStep === SurveyStep.RESPONDENT_DETAILS) {
|
|
172
|
+
this.announceToScreenReader('Submitting poll...');
|
|
173
|
+
this.submitResponse();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
prevStep() {
|
|
177
|
+
if (this.currentStep === SurveyStep.FOLLOW_UP) {
|
|
178
|
+
this.currentStep = SurveyStep.POLL;
|
|
179
|
+
}
|
|
180
|
+
else if (this.currentStep === SurveyStep.RESPONDENT_DETAILS) {
|
|
181
|
+
if (this.hasFollowUpStep()) {
|
|
182
|
+
this.currentStep = SurveyStep.FOLLOW_UP;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
this.currentStep = SurveyStep.POLL;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
hasFollowUpStep() {
|
|
190
|
+
var _a, _b, _c;
|
|
191
|
+
return !!(((_a = this.config) === null || _a === void 0 ? void 0 : _a.followUpQuestion) && ((_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.followUpChoices) === null || _c === void 0 ? void 0 : _c.length));
|
|
192
|
+
}
|
|
193
|
+
hasRespondentDetailsStep() {
|
|
194
|
+
return this.respondentDetails.length > 0;
|
|
195
|
+
}
|
|
196
|
+
announceToScreenReader(message) {
|
|
197
|
+
this.announceMessage = message;
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
this.announceMessage = '';
|
|
200
|
+
}, 1000);
|
|
201
|
+
}
|
|
202
|
+
isValidEmail(email) {
|
|
203
|
+
// Basic email validation regex
|
|
204
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
205
|
+
return emailRegex.test(email.trim());
|
|
206
|
+
}
|
|
207
|
+
validateRespondentField(detail, value) {
|
|
208
|
+
if (detail.required !== false && (!value || value.trim().length === 0)) {
|
|
209
|
+
return 'This field is required';
|
|
210
|
+
}
|
|
211
|
+
if (value && value.trim().length > 0) {
|
|
212
|
+
const config = getFieldConfig(detail, value);
|
|
213
|
+
if (config.inputType === 'email') {
|
|
214
|
+
if (!this.isValidEmail(value)) {
|
|
215
|
+
return 'Please enter a valid email address';
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
validateForm() {
|
|
222
|
+
const errors = {};
|
|
223
|
+
if (this.currentStep === SurveyStep.POLL && this.selectedChoices.length === 0) {
|
|
224
|
+
errors['poll'] = 'Please select at least one option';
|
|
225
|
+
}
|
|
226
|
+
if (this.currentStep === SurveyStep.FOLLOW_UP && this.selectedFollowUpChoices.length === 0) {
|
|
227
|
+
errors['followup'] = 'Please select at least one option';
|
|
228
|
+
}
|
|
229
|
+
this.formErrors = errors;
|
|
230
|
+
return Object.keys(errors).length === 0;
|
|
231
|
+
}
|
|
232
|
+
handleChoiceSelect(choice) {
|
|
233
|
+
var _a;
|
|
234
|
+
const choiceValue = choice.value;
|
|
235
|
+
const isMultipleChoice = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.choiceType) === 'multiChoice';
|
|
236
|
+
if (isMultipleChoice) {
|
|
237
|
+
if (this.selectedChoices.includes(choiceValue)) {
|
|
238
|
+
this.selectedChoices = this.selectedChoices.filter(c => c !== choiceValue);
|
|
239
|
+
this.announceToScreenReader(`Deselected: ${choice.label}`);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
this.selectedChoices = [...this.selectedChoices, choiceValue];
|
|
243
|
+
this.announceToScreenReader(`Selected: ${choice.label}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
this.selectedChoices = [choiceValue];
|
|
248
|
+
this.announceToScreenReader(`Selected: ${choice.label}`);
|
|
249
|
+
}
|
|
250
|
+
// Clear any validation errors when user makes a selection
|
|
251
|
+
if (this.formErrors['poll']) {
|
|
252
|
+
const errors = Object.assign({}, this.formErrors);
|
|
253
|
+
delete errors['poll'];
|
|
254
|
+
this.formErrors = errors;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
handleFollowUpChoiceSelect(choice) {
|
|
258
|
+
const choiceValue = choice.value;
|
|
259
|
+
if (this.selectedFollowUpChoices.includes(choiceValue)) {
|
|
260
|
+
this.selectedFollowUpChoices = this.selectedFollowUpChoices.filter(c => c !== choiceValue);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
this.selectedFollowUpChoices = [...this.selectedFollowUpChoices, choiceValue];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
handleRespondentDetailChange(key, event) {
|
|
267
|
+
const target = event.target;
|
|
268
|
+
const detail = this.respondentDetails.find(d => d.value === key);
|
|
269
|
+
const inputType = (detail === null || detail === void 0 ? void 0 : detail.inputType) || 'text';
|
|
270
|
+
let value;
|
|
271
|
+
if (target.type === 'checkbox') {
|
|
272
|
+
// Handle checkbox inputs - maintain comma-separated list using browser-compatible helpers
|
|
273
|
+
const currentValue = this.userRespondentDetails[key] || '';
|
|
274
|
+
const sanitizedCheckboxValue = sanitizeInput(target.value, 100);
|
|
275
|
+
if (target.checked) {
|
|
276
|
+
value = addToCommaSeparatedList(currentValue, sanitizedCheckboxValue);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
value = removeFromCommaSeparatedList(currentValue, sanitizedCheckboxValue);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
// Handle all other input types (text, email, number, radio, select)
|
|
284
|
+
// Sanitize based on field type
|
|
285
|
+
value = sanitizeByType(target.value, inputType);
|
|
286
|
+
}
|
|
287
|
+
this.userRespondentDetails = Object.assign(Object.assign({}, this.userRespondentDetails), { [key]: value });
|
|
288
|
+
}
|
|
289
|
+
createInputHandler(fieldValue) {
|
|
290
|
+
const self = this;
|
|
291
|
+
return function (e) {
|
|
292
|
+
self.handleRespondentDetailChange(fieldValue, e);
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
isValueInArray(array, value) {
|
|
296
|
+
for (let i = 0; i < array.length; i++) {
|
|
297
|
+
if (array[i] === value) {
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
renderField(detail) {
|
|
304
|
+
const config = getFieldConfig(detail, this.userRespondentDetails[detail.value] || '');
|
|
305
|
+
const inputHandler = this.createInputHandler(detail.value);
|
|
306
|
+
switch (config.inputType) {
|
|
307
|
+
case 'text':
|
|
308
|
+
case 'email':
|
|
309
|
+
case 'number':
|
|
310
|
+
return (h("input", { part: "input form-input", type: config.inputType, value: config.currentValue, onInput: inputHandler, placeholder: config.placeholder, required: config.required }));
|
|
311
|
+
case 'dropdown':
|
|
312
|
+
if (!config.hasOptions) {
|
|
313
|
+
return h("input", { part: "input form-input", type: "text", value: config.currentValue, onInput: inputHandler, placeholder: config.placeholder, required: config.required });
|
|
314
|
+
}
|
|
315
|
+
return (h("select", { part: "select form-select", onChange: inputHandler, required: config.required }, !config.defaultValue && (h("option", { value: "", disabled: true }, config.placeholder)), config.options.map(function (option) {
|
|
316
|
+
return (h("option", { key: option.value, value: option.value, selected: config.currentValue === option.value || (!config.currentValue && config.defaultValue === option.value) }, option.label));
|
|
317
|
+
})));
|
|
318
|
+
case 'radio':
|
|
319
|
+
if (!config.hasOptions) {
|
|
320
|
+
return h("input", { part: "input form-input", type: "text", value: config.currentValue, onInput: inputHandler, placeholder: config.placeholder, required: config.required });
|
|
321
|
+
}
|
|
322
|
+
return (h("div", { part: "radio-group" }, config.options.map(function (option) {
|
|
323
|
+
return (h("div", { key: option.value, part: "radio-option" }, h("input", { part: "radio-input", type: "radio", id: config.fieldValue + '-' + option.value, name: config.fieldValue, value: option.value, checked: config.currentValue === option.value || (!config.currentValue && config.defaultValue === option.value), onChange: inputHandler, required: config.required }), h("label", { part: "radio-label", htmlFor: config.fieldValue + '-' + option.value }, option.label)));
|
|
324
|
+
})));
|
|
325
|
+
case 'checkbox':
|
|
326
|
+
if (!config.hasOptions) {
|
|
327
|
+
return h("input", { part: "input form-input", type: "text", value: config.currentValue, onInput: inputHandler, placeholder: config.placeholder, required: config.required });
|
|
328
|
+
}
|
|
329
|
+
const self = this;
|
|
330
|
+
return (h("div", { part: "checkbox-group" }, config.options.map(function (option) {
|
|
331
|
+
return (h("div", { key: option.value, part: "checkbox-option" }, h("input", { part: "checkbox-input", type: "checkbox", id: config.fieldValue + '-' + option.value, name: config.fieldValue, value: option.value, checked: self.isValueInArray(config.selectedValues, option.value), onChange: inputHandler }), h("label", { part: "checkbox-label", htmlFor: config.fieldValue + '-' + option.value }, option.label)));
|
|
332
|
+
})));
|
|
333
|
+
default:
|
|
334
|
+
return h("input", { part: "input form-input", type: "text", value: config.currentValue, onInput: inputHandler, placeholder: config.placeholder, required: config.required });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
isRespondentDetailsValid() {
|
|
338
|
+
return this.respondentDetails.every(detail => {
|
|
339
|
+
const value = this.userRespondentDetails[detail.value] || '';
|
|
340
|
+
const error = this.validateRespondentField(detail, value);
|
|
341
|
+
return error === null;
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
renderPollStep() {
|
|
345
|
+
var _a, _b, _c, _d;
|
|
346
|
+
const isFinalStep = !this.hasFollowUpStep() && !this.hasRespondentDetailsStep();
|
|
347
|
+
const isMultiple = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.choiceType) === 'multiChoice';
|
|
348
|
+
const hasError = !!this.formErrors['poll'];
|
|
349
|
+
return (h("div", { part: "step poll-step" }, h("h2", { part: "heading poll-heading", id: "poll-heading" }, ((_b = this.config) === null || _b === void 0 ? void 0 : _b.question) || 'What is your choice?'), h("div", { part: "choices-container", role: isMultiple ? 'group' : 'radiogroup', "aria-labelledby": "poll-heading", "aria-invalid": hasError, "aria-describedby": hasError ? 'poll-error' : undefined }, (_d = (_c = this.config) === null || _c === void 0 ? void 0 : _c.choices) === null || _d === void 0 ? void 0 : _d.map((choice, index) => (h("label", { part: "choice-option", key: choice.value }, h("input", { part: isMultiple ? 'checkbox-input' : 'radio-input', type: isMultiple ? 'checkbox' : 'radio', id: `poll-choice-${index}`, name: "poll-choice", value: choice.value, checked: this.selectedChoices.includes(choice.value), onChange: () => this.handleChoiceSelect(choice), "aria-describedby": `poll-choice-${index}-label` }), h("span", { part: "choice-label", id: `poll-choice-${index}-label` }, choice.label))))), hasError && (h("div", { part: "error-message", id: "poll-error", role: "alert", "aria-live": "polite" }, this.formErrors['poll'])), h("div", { part: "button-container" }, h("button", { part: "button next-button", onClick: () => this.nextStep(), disabled: this.selectedChoices.length === 0 }, isFinalStep ? 'Submit' : 'Next'))));
|
|
350
|
+
}
|
|
351
|
+
renderFollowUpStep() {
|
|
352
|
+
var _a, _b, _c;
|
|
353
|
+
const isFinalStep = !this.hasRespondentDetailsStep();
|
|
354
|
+
return (h("div", { part: "step follow-up-step" }, h("h2", { part: "heading follow-up-heading" }, ((_a = this.config) === null || _a === void 0 ? void 0 : _a.followUpQuestion) || 'Follow-up question'), h("div", { part: "choices-container" }, (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.followUpChoices) === null || _c === void 0 ? void 0 : _c.map(choice => (h("label", { part: "choice-option", key: choice.value }, h("input", { part: "checkbox-input", type: "checkbox", name: "follow-up-choice", value: choice.value, checked: this.selectedFollowUpChoices.includes(choice.value), onChange: () => this.handleFollowUpChoiceSelect(choice) }), h("span", { part: "choice-label" }, choice.label))))), h("div", { part: "button-container" }, h("button", { part: "button back-button", onClick: () => this.prevStep() }, "Back"), h("button", { part: "button next-button", onClick: () => this.nextStep() }, isFinalStep ? 'Submit' : 'Next'))));
|
|
355
|
+
}
|
|
356
|
+
renderRespondentDetailsStep() {
|
|
357
|
+
return (h("div", { part: "step respondent-details-step" }, h("h2", { part: "heading respondent-details-heading" }, "Tell us about yourself"), h("div", { part: "form-container" }, this.respondentDetails.map(detail => (h("div", { part: "form-field" }, h("label", { part: "form-label" }, detail.label, detail.required && h("span", { part: "required-indicator" }, " *")), this.renderField(detail))))), h("div", { part: "button-container" }, h("button", { part: "button back-button", onClick: () => this.prevStep() }, "Back"), h("button", { part: "button submit-button", onClick: () => this.submitResponse(), disabled: !this.isRespondentDetailsValid() }, "Submit"))));
|
|
358
|
+
}
|
|
359
|
+
renderCompletionStep() {
|
|
360
|
+
return (h("div", { part: "step completion-step" }, h("h2", { part: "heading completion-heading" }, this.completionMessage)));
|
|
361
|
+
}
|
|
362
|
+
renderCurrentStep() {
|
|
363
|
+
const stepRenderers = {
|
|
364
|
+
[SurveyStep.POLL]: this.renderPollStep.bind(this),
|
|
365
|
+
[SurveyStep.FOLLOW_UP]: this.renderFollowUpStep.bind(this),
|
|
366
|
+
[SurveyStep.RESPONDENT_DETAILS]: this.renderRespondentDetailsStep.bind(this),
|
|
367
|
+
[SurveyStep.COMPLETION]: this.renderCompletionStep.bind(this),
|
|
368
|
+
};
|
|
369
|
+
const renderer = stepRenderers[this.currentStep] || stepRenderers[SurveyStep.POLL];
|
|
370
|
+
return renderer();
|
|
371
|
+
}
|
|
372
|
+
render() {
|
|
373
|
+
if (!isValidKey(this.surveyKey)) {
|
|
374
|
+
return (h(Host, null, h("p", { part: "message error-message" }, "Unable to render survey due to invalid public key")));
|
|
375
|
+
}
|
|
376
|
+
if (this.loading) {
|
|
377
|
+
return (h(Host, null, h("p", { part: "message loading-message" }, "Loading survey...")));
|
|
378
|
+
}
|
|
379
|
+
if (this.error) {
|
|
380
|
+
return (h(Host, null, h("div", { part: "error-container" }, h("p", { part: "message error-message" }, this.error), h("button", { part: "button retry-button", onClick: () => this.retryOperation() }, "Try again"))));
|
|
381
|
+
}
|
|
382
|
+
if (!this.config) {
|
|
383
|
+
return (h(Host, null, h("div", { part: "error-container" }, h("p", { part: "message error-message" }, "No survey configuration found"), h("button", { part: "button retry-button", onClick: () => this.retryOperation() }, "Try again"))));
|
|
384
|
+
}
|
|
385
|
+
return (h(Host, null, h("div", { part: "survey-container", role: "main", "aria-label": "Poll Survey" }, this.renderCurrentStep(), h("div", { "aria-live": "polite", "aria-atomic": "true", class: "sr-only", part: "announcements" }, this.announceMessage))));
|
|
386
|
+
}
|
|
387
|
+
get el() { return this; }
|
|
388
|
+
static get style() { return sfFastpollCss; }
|
|
389
|
+
}, [1, "sf-fastpoll", {
|
|
390
|
+
"surveyKey": [1, "survey-key"],
|
|
391
|
+
"completionMessage": [1, "completion-message"],
|
|
392
|
+
"config": [32],
|
|
393
|
+
"respondentDetails": [32],
|
|
394
|
+
"loading": [32],
|
|
395
|
+
"error": [32],
|
|
396
|
+
"currentStep": [32],
|
|
397
|
+
"selectedChoices": [32],
|
|
398
|
+
"selectedFollowUpChoices": [32],
|
|
399
|
+
"userRespondentDetails": [32],
|
|
400
|
+
"submitted": [32],
|
|
401
|
+
"announceMessage": [32],
|
|
402
|
+
"formErrors": [32]
|
|
403
|
+
}]);
|
|
404
|
+
function defineCustomElement$1() {
|
|
405
|
+
if (typeof customElements === "undefined") {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const components = ["sf-fastpoll"];
|
|
409
|
+
components.forEach(tagName => { switch (tagName) {
|
|
410
|
+
case "sf-fastpoll":
|
|
411
|
+
if (!customElements.get(tagName)) {
|
|
412
|
+
customElements.define(tagName, SfFastpoll$1);
|
|
413
|
+
}
|
|
414
|
+
break;
|
|
415
|
+
} });
|
|
416
|
+
}
|
|
417
|
+
defineCustomElement$1();
|
|
418
|
+
|
|
419
|
+
const SfFastpoll = SfFastpoll$1;
|
|
420
|
+
const defineCustomElement = defineCustomElement$1;
|
|
421
|
+
|
|
422
|
+
export { SfFastpoll, defineCustomElement };
|
|
423
|
+
//# sourceMappingURL=sf-fastpoll.js.map
|
|
424
|
+
|
|
425
|
+
//# sourceMappingURL=sf-fastpoll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"file":"sf-fastpoll.js","mappings":"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","names":["SfFastpoll","__stencil_proxyCustomElement","HTMLElement"],"sources":["src/components/sf-fastpoll/sf-fastpoll.css?tag=sf-fastpoll&encapsulation=shadow","src/components/sf-fastpoll/sf-fastpoll.tsx"],"sourcesContent":[":host {\n display: block;\n}\n\n/* Screen reader only content */\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n/* Focus indicators for accessibility */\ninput:focus,\nselect:focus,\nbutton:focus {\n outline: 2px solid #005fcc;\n outline-offset: 2px;\n}\n\n/* Error state styling */\n[aria-invalid='true'] {\n border-color: #d32f2f;\n}\n\n[part='error-message'] {\n color: #d32f2f;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n/* Choice options styling */\n[part='choice-option'] {\n display: flex;\n align-items: center;\n margin: 0.5rem 0;\n cursor: pointer;\n}\n\n[part='choice-option']:hover {\n background-color: rgba(0, 95, 204, 0.1);\n}\n\n/* High contrast mode support */\n@media (prefers-contrast: high) {\n input:focus,\n select:focus,\n button:focus {\n outline: 3px solid;\n }\n\n [part='error-message'] {\n background-color: #d32f2f;\n color: white;\n padding: 0.25rem;\n }\n\n [part='choice-option']:hover {\n background-color: highlight;\n color: highlighttext;\n }\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n * {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n","import { Component, Host, h, Prop, State, Element, Env } from '@stencil/core';\nimport { isValidKey, getFieldConfig, addToCommaSeparatedList, removeFromCommaSeparatedList, sanitizeByType, sanitizeInput } from '../../utils/utils';\n\nconst SURVEY_API_ENDPOINT = Env.SURVEY_API_ENDPOINT;\nconst RESPONSE_API_ENDPOINT = Env.RESPONSE_API_ENDPOINT;\n\nenum SurveyStep {\n POLL = 0,\n FOLLOW_UP = 1,\n RESPONDENT_DETAILS = 2,\n COMPLETION = 3,\n}\n\ninterface RespondentDetail {\n label: string;\n value: string;\n inputType: string; // 'text', 'email', 'dropdown', 'radio', 'checkbox', 'number'\n required?: boolean;\n placeholder?: string;\n options?: Array<{\n value: string;\n label: string;\n }>;\n defaultValue?: any;\n}\n\ninterface Choice {\n label: string;\n value: string;\n}\n\ninterface SurveyConfig {\n question: string;\n choiceType: string; // 'single' or 'multiple'\n choices: Choice[];\n followUpChoices?: Choice[];\n followUpQuestion?: string;\n}\n\ninterface SurveyPayload {\n config: SurveyConfig;\n respondentDetails?: RespondentDetail[];\n}\n\ninterface ApiResponse {\n success: boolean;\n message: string;\n payload: SurveyPayload;\n}\n\n@Component({\n tag: 'sf-fastpoll',\n styleUrl: 'sf-fastpoll.css',\n shadow: true,\n})\nexport class SfFastpoll {\n @Element() el: HTMLElement;\n\n @Prop() surveyKey: string;\n\n @Prop() completionMessage: string = 'Thank you for your response!';\n\n @State() config: SurveyConfig | null = null;\n\n @State() respondentDetails: RespondentDetail[] = [];\n\n @State() loading: boolean = false;\n\n @State() error: string | null = null;\n\n @State() currentStep: SurveyStep = SurveyStep.POLL;\n\n @State() selectedChoices: string[] = [];\n\n @State() selectedFollowUpChoices: string[] = [];\n\n @State() userRespondentDetails: { [key: string]: string } = {};\n\n @State() submitted: boolean = false;\n\n @State() announceMessage: string = '';\n\n @State() formErrors: { [key: string]: string } = {};\n\n private surveyStartTime: number = 0;\n\n componentWillLoad() {\n if (isValidKey(this.surveyKey)) {\n return this.fetchSurveyData();\n }\n return Promise.resolve();\n }\n\n private async fetchSurveyData() {\n this.loading = true;\n this.error = null;\n this.surveyStartTime = Date.now();\n\n try {\n const response = await fetch(`${SURVEY_API_ENDPOINT}/${this.surveyKey}`);\n const data: ApiResponse = await response.json();\n\n if (!data.success) {\n throw new Error(data.message);\n }\n\n this.config = data.payload.config;\n this.respondentDetails = data.payload.respondentDetails || [];\n } catch (error) {\n this.error = error instanceof Error ? error.message : String(error);\n } finally {\n this.loading = false;\n }\n }\n\n private async retryOperation() {\n if (this.config) {\n // If we have config, retry submission\n await this.submitResponse();\n } else {\n // Otherwise, retry fetching survey data\n await this.fetchSurveyData();\n }\n }\n\n private async submitResponse() {\n if (!this.config || this.submitted) {\n return;\n }\n\n this.loading = true;\n this.error = null;\n\n try {\n const completionTimeSeconds = this.surveyStartTime > 0 ? Math.round((Date.now() - this.surveyStartTime) / 1000) : 0;\n const userAgentInfo = this.getUserAgentInfo();\n\n const submissionData = {\n surveyPublicKey: this.surveyKey,\n responseData: {\n selectedChoices: this.selectedChoices,\n selectedFollowUpChoices: this.selectedFollowUpChoices,\n },\n respondentDetails: this.userRespondentDetails,\n userAgent: userAgentInfo,\n completionTime: completionTimeSeconds,\n surveyType: 'fastPoll',\n };\n\n const response = await fetch(`${RESPONSE_API_ENDPOINT}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(submissionData),\n });\n\n const result = await response.json();\n\n if (!result.success) {\n throw new Error(result.message);\n }\n\n this.submitted = true;\n this.currentStep = SurveyStep.COMPLETION;\n } catch (error) {\n this.error = error instanceof Error ? error.message : String(error);\n } finally {\n this.loading = false;\n }\n }\n\n private getUserAgentInfo() {\n // Use modern navigator.userAgentData when available, fallback to userAgent parsing\n const getPlatform = () => {\n if ('userAgentData' in navigator && (navigator as any).userAgentData?.platform) {\n return (navigator as any).userAgentData.platform;\n }\n // Fallback: extract platform info from userAgent\n const ua = navigator.userAgent;\n if (ua.includes('Win')) return 'Windows';\n if (ua.includes('Mac')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iOS')) return 'iOS';\n return 'Unknown';\n };\n\n return {\n userAgent: navigator.userAgent,\n language: navigator.language,\n platform: getPlatform(),\n cookieEnabled: navigator.cookieEnabled,\n onLine: navigator.onLine,\n screenResolution: `${screen.width}x${screen.height}`,\n colorDepth: screen.colorDepth,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n timestamp: new Date().toISOString(),\n };\n }\n\n private nextStep() {\n if (!this.validateForm()) {\n return;\n }\n\n if (this.currentStep === SurveyStep.POLL) {\n if (this.hasFollowUpStep()) {\n this.currentStep = SurveyStep.FOLLOW_UP;\n this.announceToScreenReader('Moving to follow-up question');\n } else if (this.hasRespondentDetailsStep()) {\n this.currentStep = SurveyStep.RESPONDENT_DETAILS;\n this.announceToScreenReader('Moving to respondent details');\n } else {\n this.announceToScreenReader('Submitting poll...');\n this.submitResponse();\n }\n } else if (this.currentStep === SurveyStep.FOLLOW_UP) {\n if (this.hasRespondentDetailsStep()) {\n this.currentStep = SurveyStep.RESPONDENT_DETAILS;\n this.announceToScreenReader('Moving to respondent details');\n } else {\n this.announceToScreenReader('Submitting poll...');\n this.submitResponse();\n }\n } else if (this.currentStep === SurveyStep.RESPONDENT_DETAILS) {\n this.announceToScreenReader('Submitting poll...');\n this.submitResponse();\n }\n }\n\n private prevStep() {\n if (this.currentStep === SurveyStep.FOLLOW_UP) {\n this.currentStep = SurveyStep.POLL;\n } else if (this.currentStep === SurveyStep.RESPONDENT_DETAILS) {\n if (this.hasFollowUpStep()) {\n this.currentStep = SurveyStep.FOLLOW_UP;\n } else {\n this.currentStep = SurveyStep.POLL;\n }\n }\n }\n\n private hasFollowUpStep(): boolean {\n return !!(this.config?.followUpQuestion && this.config?.followUpChoices?.length);\n }\n\n private hasRespondentDetailsStep(): boolean {\n return this.respondentDetails.length > 0;\n }\n\n private announceToScreenReader(message: string) {\n this.announceMessage = message;\n setTimeout(() => {\n this.announceMessage = '';\n }, 1000);\n }\n\n private isValidEmail(email: string): boolean {\n // Basic email validation regex\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(email.trim());\n }\n\n private validateRespondentField(detail: RespondentDetail, value: string): string | null {\n if (detail.required !== false && (!value || value.trim().length === 0)) {\n return 'This field is required';\n }\n\n if (value && value.trim().length > 0) {\n const config = getFieldConfig(detail, value);\n if (config.inputType === 'email') {\n if (!this.isValidEmail(value)) {\n return 'Please enter a valid email address';\n }\n }\n }\n\n return null;\n }\n\n private validateForm(): boolean {\n const errors: { [key: string]: string } = {};\n\n if (this.currentStep === SurveyStep.POLL && this.selectedChoices.length === 0) {\n errors['poll'] = 'Please select at least one option';\n }\n\n if (this.currentStep === SurveyStep.FOLLOW_UP && this.selectedFollowUpChoices.length === 0) {\n errors['followup'] = 'Please select at least one option';\n }\n\n this.formErrors = errors;\n return Object.keys(errors).length === 0;\n }\n\n private handleChoiceSelect(choice: Choice) {\n const choiceValue = choice.value;\n const isMultipleChoice = this.config?.choiceType === 'multiChoice';\n\n if (isMultipleChoice) {\n if (this.selectedChoices.includes(choiceValue)) {\n this.selectedChoices = this.selectedChoices.filter(c => c !== choiceValue);\n this.announceToScreenReader(`Deselected: ${choice.label}`);\n } else {\n this.selectedChoices = [...this.selectedChoices, choiceValue];\n this.announceToScreenReader(`Selected: ${choice.label}`);\n }\n } else {\n this.selectedChoices = [choiceValue];\n this.announceToScreenReader(`Selected: ${choice.label}`);\n }\n\n // Clear any validation errors when user makes a selection\n if (this.formErrors['poll']) {\n const errors = { ...this.formErrors };\n delete errors['poll'];\n this.formErrors = errors;\n }\n }\n\n private handleFollowUpChoiceSelect(choice: Choice) {\n const choiceValue = choice.value;\n if (this.selectedFollowUpChoices.includes(choiceValue)) {\n this.selectedFollowUpChoices = this.selectedFollowUpChoices.filter(c => c !== choiceValue);\n } else {\n this.selectedFollowUpChoices = [...this.selectedFollowUpChoices, choiceValue];\n }\n }\n\n private handleRespondentDetailChange(key: string, event: Event) {\n const target = event.target as HTMLInputElement | HTMLSelectElement;\n const detail = this.respondentDetails.find(d => d.value === key);\n const inputType = detail?.inputType || 'text';\n let value: string;\n\n if (target.type === 'checkbox') {\n // Handle checkbox inputs - maintain comma-separated list using browser-compatible helpers\n const currentValue = this.userRespondentDetails[key] || '';\n const sanitizedCheckboxValue = sanitizeInput(target.value, 100);\n if (target.checked) {\n value = addToCommaSeparatedList(currentValue, sanitizedCheckboxValue);\n } else {\n value = removeFromCommaSeparatedList(currentValue, sanitizedCheckboxValue);\n }\n } else {\n // Handle all other input types (text, email, number, radio, select)\n // Sanitize based on field type\n value = sanitizeByType(target.value, inputType);\n }\n\n this.userRespondentDetails = {\n ...this.userRespondentDetails,\n [key]: value,\n };\n }\n\n private createInputHandler(fieldValue: string) {\n const self = this;\n return function (e: Event) {\n self.handleRespondentDetailChange(fieldValue, e);\n };\n }\n\n private isValueInArray(array: string[], value: string): boolean {\n for (let i = 0; i < array.length; i++) {\n if (array[i] === value) {\n return true;\n }\n }\n return false;\n }\n\n private renderField(detail: RespondentDetail) {\n const config = getFieldConfig(detail, this.userRespondentDetails[detail.value] || '');\n const inputHandler = this.createInputHandler(detail.value);\n\n switch (config.inputType) {\n case 'text':\n case 'email':\n case 'number':\n return (\n <input part=\"input form-input\" type={config.inputType} value={config.currentValue} onInput={inputHandler} placeholder={config.placeholder} required={config.required} />\n );\n\n case 'dropdown':\n if (!config.hasOptions) {\n return <input part=\"input form-input\" type=\"text\" value={config.currentValue} onInput={inputHandler} placeholder={config.placeholder} required={config.required} />;\n }\n return (\n <select part=\"select form-select\" onChange={inputHandler} required={config.required}>\n {!config.defaultValue && (\n <option value=\"\" disabled>\n {config.placeholder}\n </option>\n )}\n {config.options.map(function (option) {\n return (\n <option key={option.value} value={option.value} selected={config.currentValue === option.value || (!config.currentValue && config.defaultValue === option.value)}>\n {option.label}\n </option>\n );\n })}\n </select>\n );\n\n case 'radio':\n if (!config.hasOptions) {\n return <input part=\"input form-input\" type=\"text\" value={config.currentValue} onInput={inputHandler} placeholder={config.placeholder} required={config.required} />;\n }\n return (\n <div part=\"radio-group\">\n {config.options.map(function (option) {\n return (\n <div key={option.value} part=\"radio-option\">\n <input\n part=\"radio-input\"\n type=\"radio\"\n id={config.fieldValue + '-' + option.value}\n name={config.fieldValue}\n value={option.value}\n checked={config.currentValue === option.value || (!config.currentValue && config.defaultValue === option.value)}\n onChange={inputHandler}\n required={config.required}\n />\n <label part=\"radio-label\" htmlFor={config.fieldValue + '-' + option.value}>\n {option.label}\n </label>\n </div>\n );\n })}\n </div>\n );\n\n case 'checkbox':\n if (!config.hasOptions) {\n return <input part=\"input form-input\" type=\"text\" value={config.currentValue} onInput={inputHandler} placeholder={config.placeholder} required={config.required} />;\n }\n const self = this;\n return (\n <div part=\"checkbox-group\">\n {config.options.map(function (option) {\n return (\n <div key={option.value} part=\"checkbox-option\">\n <input\n part=\"checkbox-input\"\n type=\"checkbox\"\n id={config.fieldValue + '-' + option.value}\n name={config.fieldValue}\n value={option.value}\n checked={self.isValueInArray(config.selectedValues, option.value)}\n onChange={inputHandler}\n />\n <label part=\"checkbox-label\" htmlFor={config.fieldValue + '-' + option.value}>\n {option.label}\n </label>\n </div>\n );\n })}\n </div>\n );\n\n default:\n return <input part=\"input form-input\" type=\"text\" value={config.currentValue} onInput={inputHandler} placeholder={config.placeholder} required={config.required} />;\n }\n }\n\n private isRespondentDetailsValid(): boolean {\n return this.respondentDetails.every(detail => {\n const value = this.userRespondentDetails[detail.value] || '';\n const error = this.validateRespondentField(detail, value);\n return error === null;\n });\n }\n\n private renderPollStep() {\n const isFinalStep = !this.hasFollowUpStep() && !this.hasRespondentDetailsStep();\n const isMultiple = this.config?.choiceType === 'multiChoice';\n const hasError = !!this.formErrors['poll'];\n\n return (\n <div part=\"step poll-step\">\n <h2 part=\"heading poll-heading\" id=\"poll-heading\">\n {this.config?.question || 'What is your choice?'}\n </h2>\n <div\n part=\"choices-container\"\n role={isMultiple ? 'group' : 'radiogroup'}\n aria-labelledby=\"poll-heading\"\n aria-invalid={hasError}\n aria-describedby={hasError ? 'poll-error' : undefined}\n >\n {this.config?.choices?.map((choice, index) => (\n <label part=\"choice-option\" key={choice.value}>\n <input\n part={isMultiple ? 'checkbox-input' : 'radio-input'}\n type={isMultiple ? 'checkbox' : 'radio'}\n id={`poll-choice-${index}`}\n name=\"poll-choice\"\n value={choice.value}\n checked={this.selectedChoices.includes(choice.value)}\n onChange={() => this.handleChoiceSelect(choice)}\n aria-describedby={`poll-choice-${index}-label`}\n />\n <span part=\"choice-label\" id={`poll-choice-${index}-label`}>\n {choice.label}\n </span>\n </label>\n ))}\n </div>\n {hasError && (\n <div part=\"error-message\" id=\"poll-error\" role=\"alert\" aria-live=\"polite\">\n {this.formErrors['poll']}\n </div>\n )}\n <div part=\"button-container\">\n <button part=\"button next-button\" onClick={() => this.nextStep()} disabled={this.selectedChoices.length === 0}>\n {isFinalStep ? 'Submit' : 'Next'}\n </button>\n </div>\n </div>\n );\n }\n\n private renderFollowUpStep() {\n const isFinalStep = !this.hasRespondentDetailsStep();\n\n return (\n <div part=\"step follow-up-step\">\n <h2 part=\"heading follow-up-heading\">{this.config?.followUpQuestion || 'Follow-up question'}</h2>\n <div part=\"choices-container\">\n {this.config?.followUpChoices?.map(choice => (\n <label part=\"choice-option\" key={choice.value}>\n <input\n part=\"checkbox-input\"\n type=\"checkbox\"\n name=\"follow-up-choice\"\n value={choice.value}\n checked={this.selectedFollowUpChoices.includes(choice.value)}\n onChange={() => this.handleFollowUpChoiceSelect(choice)}\n />\n <span part=\"choice-label\">{choice.label}</span>\n </label>\n ))}\n </div>\n <div part=\"button-container\">\n <button part=\"button back-button\" onClick={() => this.prevStep()}>\n Back\n </button>\n <button part=\"button next-button\" onClick={() => this.nextStep()}>\n {isFinalStep ? 'Submit' : 'Next'}\n </button>\n </div>\n </div>\n );\n }\n\n private renderRespondentDetailsStep() {\n return (\n <div part=\"step respondent-details-step\">\n <h2 part=\"heading respondent-details-heading\">Tell us about yourself</h2>\n <div part=\"form-container\">\n {this.respondentDetails.map(detail => (\n <div part=\"form-field\">\n <label part=\"form-label\">\n {detail.label}\n {detail.required && <span part=\"required-indicator\"> *</span>}\n </label>\n {this.renderField(detail)}\n </div>\n ))}\n </div>\n <div part=\"button-container\">\n <button part=\"button back-button\" onClick={() => this.prevStep()}>\n Back\n </button>\n <button part=\"button submit-button\" onClick={() => this.submitResponse()} disabled={!this.isRespondentDetailsValid()}>\n Submit\n </button>\n </div>\n </div>\n );\n }\n\n private renderCompletionStep() {\n return (\n <div part=\"step completion-step\">\n <h2 part=\"heading completion-heading\">{this.completionMessage}</h2>\n </div>\n );\n }\n\n private renderCurrentStep() {\n const stepRenderers = {\n [SurveyStep.POLL]: this.renderPollStep.bind(this),\n [SurveyStep.FOLLOW_UP]: this.renderFollowUpStep.bind(this),\n [SurveyStep.RESPONDENT_DETAILS]: this.renderRespondentDetailsStep.bind(this),\n [SurveyStep.COMPLETION]: this.renderCompletionStep.bind(this),\n };\n\n const renderer = stepRenderers[this.currentStep] || stepRenderers[SurveyStep.POLL];\n\n return renderer();\n }\n\n render() {\n if (!isValidKey(this.surveyKey)) {\n return (\n <Host>\n <p part=\"message error-message\">Unable to render survey due to invalid public key</p>\n </Host>\n );\n }\n\n if (this.loading) {\n return (\n <Host>\n <p part=\"message loading-message\">Loading survey...</p>\n </Host>\n );\n }\n\n if (this.error) {\n return (\n <Host>\n <div part=\"error-container\">\n <p part=\"message error-message\">{this.error}</p>\n <button part=\"button retry-button\" onClick={() => this.retryOperation()}>\n Try again\n </button>\n </div>\n </Host>\n );\n }\n\n if (!this.config) {\n return (\n <Host>\n <div part=\"error-container\">\n <p part=\"message error-message\">No survey configuration found</p>\n <button part=\"button retry-button\" onClick={() => this.retryOperation()}>\n Try again\n </button>\n </div>\n </Host>\n );\n }\n\n return (\n <Host>\n <div part=\"survey-container\" role=\"main\" aria-label=\"Poll Survey\">\n {this.renderCurrentStep()}\n {/* ARIA live region for screen reader announcements */}\n <div aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\" part=\"announcements\">\n {this.announceMessage}\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"version":3}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-globals-DQuL1Twl.js","sources":["@stencil/core/internal/app-globals"],"sourcesContent":["export const globalScripts = () => {};\nexport const globalStyles = \"\";\n"],"names":[],"mappings":"AAAY,MAAC,aAAa,GAAG,MAAM;;;;"}
|