@fullsession.io/fs-feedback-widget 1.11.0 → 1.13.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/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/App.svelte +8 -1
- package/src/Icons/reactionIcons.svelte +19 -55
- package/src/widgetPages/App.css +91 -12
- package/src/widgetPages/reactionPage.svelte +77 -54
- package/src/widgetPages/reactionpage.css +302 -55
package/package.json
CHANGED
package/src/App.svelte
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
$: widgetLanguage = feedback.wgLanguage;
|
|
16
16
|
$: widgetAlternateColor = feedback.wgAlternateColor;
|
|
17
17
|
$: wgPosition = feedback.wgPosition;
|
|
18
|
+
$: widgetThanksComponentActivation = feedback.wgThanksMsgActivation;
|
|
18
19
|
$: widgetThanksMsg = feedback.wgThanksMsg;
|
|
19
20
|
$: WidgetTriggers = feedback.wgTriggers;
|
|
20
21
|
$: document.documentElement.style.setProperty("--widgetColor", widgetColor);
|
|
@@ -205,7 +206,13 @@
|
|
|
205
206
|
|
|
206
207
|
const openThanksMessage = () => {
|
|
207
208
|
visible = !visible;
|
|
208
|
-
|
|
209
|
+
if (widgetThanksComponentActivation) {
|
|
210
|
+
thanksMessageVisible = !thanksMessageVisible;
|
|
211
|
+
} else {
|
|
212
|
+
setTimeout(function () {
|
|
213
|
+
buttonVisible = !buttonVisible;
|
|
214
|
+
}, 350);
|
|
215
|
+
}
|
|
209
216
|
};
|
|
210
217
|
|
|
211
218
|
const closeThanksMessage = () => {
|
|
@@ -5,68 +5,32 @@
|
|
|
5
5
|
export let emotIconType;
|
|
6
6
|
export let width = "40px";
|
|
7
7
|
export let height = "40px";
|
|
8
|
-
|
|
8
|
+
// Recompute emotIcons and icons reactively when `emotIconType` changes
|
|
9
|
+
$: emotIcons =
|
|
9
10
|
emotIconType == "0"
|
|
10
11
|
? icons_1
|
|
11
12
|
: emotIconType == "1"
|
|
12
13
|
? icons_2
|
|
13
14
|
: emotIconType == "2"
|
|
14
15
|
? icons_3
|
|
15
|
-
:
|
|
16
|
-
let icons = [
|
|
17
|
-
{
|
|
18
|
-
box: 50,
|
|
19
|
-
name: "love",
|
|
20
|
-
svg: emotIcons[0],
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
box: 50,
|
|
24
|
-
name: "unSelectedLove",
|
|
25
|
-
svg: emotIcons[1],
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
box: 50,
|
|
29
|
-
name: "like",
|
|
30
|
-
svg: emotIcons[2],
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
box: 50,
|
|
34
|
-
name: "unSelectedLike",
|
|
35
|
-
svg: emotIcons[3],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
box: 50,
|
|
39
|
-
name: "neutral",
|
|
40
|
-
svg: emotIcons[4],
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
box: 50,
|
|
44
|
-
name: "unSelectedNeutral",
|
|
45
|
-
svg: emotIcons[5],
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
box: 50,
|
|
49
|
-
name: "dislike",
|
|
50
|
-
svg: emotIcons[6],
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
box: 50,
|
|
54
|
-
name: "unSelectedDislike",
|
|
55
|
-
svg: emotIcons[7],
|
|
56
|
-
},
|
|
16
|
+
: icons_1;
|
|
57
17
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
18
|
+
$: icons = emotIcons
|
|
19
|
+
? [
|
|
20
|
+
{ box: 50, name: "love", svg: emotIcons[0] },
|
|
21
|
+
{ box: 50, name: "unSelectedLove", svg: emotIcons[1] },
|
|
22
|
+
{ box: 50, name: "like", svg: emotIcons[2] },
|
|
23
|
+
{ box: 50, name: "unSelectedLike", svg: emotIcons[3] },
|
|
24
|
+
{ box: 50, name: "neutral", svg: emotIcons[4] },
|
|
25
|
+
{ box: 50, name: "unSelectedNeutral", svg: emotIcons[5] },
|
|
26
|
+
{ box: 50, name: "dislike", svg: emotIcons[6] },
|
|
27
|
+
{ box: 50, name: "unSelectedDislike", svg: emotIcons[7] },
|
|
28
|
+
{ box: 50, name: "hate", svg: emotIcons[8] },
|
|
29
|
+
{ box: 50, name: "unSelectedHate", svg: emotIcons[9] },
|
|
30
|
+
]
|
|
31
|
+
: [];
|
|
32
|
+
|
|
33
|
+
$: displayIcon = icons.find((e) => e.name === name) || icons[0];
|
|
70
34
|
</script>
|
|
71
35
|
|
|
72
36
|
{#if emotIconType === "2"}
|
package/src/widgetPages/App.css
CHANGED
|
@@ -32,12 +32,13 @@
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
.fs-thanks-txt {
|
|
35
|
-
width:
|
|
36
|
-
padding: 20px
|
|
35
|
+
width: 100%;
|
|
36
|
+
padding: 20px;
|
|
37
37
|
text-align: center;
|
|
38
38
|
align-self: center;
|
|
39
39
|
padding-bottom: 20px;
|
|
40
|
-
overflow:
|
|
40
|
+
overflow-y: auto;
|
|
41
|
+
max-height: 100%;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
fsContainerApp {
|
|
@@ -121,7 +122,9 @@ fsContainerApp {
|
|
|
121
122
|
display: flex;
|
|
122
123
|
flex-direction: column;
|
|
123
124
|
pointer-events: auto;
|
|
124
|
-
|
|
125
|
+
width: 320px;
|
|
126
|
+
height: 150px;
|
|
127
|
+
border-radius: 5px;
|
|
125
128
|
background-color: rgb(255, 255, 255);
|
|
126
129
|
margin-right: var(--widgetMarginRight);
|
|
127
130
|
margin-left: var(--widgetMarginLeft);
|
|
@@ -155,12 +158,88 @@ fsContainerApp {
|
|
|
155
158
|
margin-left: 90% !important;
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
/* Mobile Responsive Styles */
|
|
162
|
+
@media (max-width: 768px) {
|
|
163
|
+
.fsCont {
|
|
164
|
+
width: 90vw;
|
|
165
|
+
max-width: 320px;
|
|
166
|
+
margin-right: 5vw;
|
|
167
|
+
margin-left: 5vw;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.fsContNps {
|
|
171
|
+
width: 95vw !important;
|
|
172
|
+
max-width: 400px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.fsThanksMessageCont {
|
|
176
|
+
width: 90vw;
|
|
177
|
+
max-width: 320px;
|
|
178
|
+
margin-right: 5vw;
|
|
179
|
+
margin-left: 5vw;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.fsWidget {
|
|
183
|
+
width: 32px;
|
|
184
|
+
height: 110px;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#fsFeedbackTxt {
|
|
188
|
+
font-size: 13px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.fsCloseCont {
|
|
192
|
+
margin-left: 82%;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.fsNpsCloseCont {
|
|
196
|
+
margin-left: 88% !important;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.fs-thanks-txt {
|
|
200
|
+
width: 100%;
|
|
201
|
+
padding: 15px;
|
|
202
|
+
font-size: 14px;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
158
205
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
206
|
+
@media (max-width: 480px) {
|
|
207
|
+
.fsCont {
|
|
208
|
+
width: 95vw;
|
|
209
|
+
max-width: 300px;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.fsContNps {
|
|
213
|
+
width: 98vw !important;
|
|
214
|
+
max-width: 380px;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.fsThanksMessageCont {
|
|
218
|
+
width: 95vw;
|
|
219
|
+
max-width: 300px;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.fsWidget {
|
|
223
|
+
width: 30px;
|
|
224
|
+
height: 100px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#fsFeedbackTxt {
|
|
228
|
+
font-size: 12px;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.fsCloseCont {
|
|
232
|
+
width: 24px;
|
|
233
|
+
height: 24px;
|
|
234
|
+
margin-left: 80%;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
#fsCloseIcon {
|
|
238
|
+
font-size: 13px;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.fs-thanks-txt {
|
|
242
|
+
font-size: 13px;
|
|
243
|
+
padding: 12px;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import Icons from "../Icons/reactionIcons.svelte";
|
|
3
3
|
import "../widgetPages/reactionpage.css";
|
|
4
|
+
import { onMount } from "svelte";
|
|
5
|
+
|
|
4
6
|
export let feedbackData;
|
|
5
7
|
export let wgType;
|
|
6
8
|
$: widgetComponent = 1;
|
|
@@ -20,30 +22,43 @@
|
|
|
20
22
|
$: loveDisplay = "none";
|
|
21
23
|
$: buttonColor = feedbackData.wgAccentColor;
|
|
22
24
|
$: widgetQuestion = feedbackData.wgQuestion;
|
|
25
|
+
$: widgetEmailComponentActivation = feedbackData.wgEmailReqActivation;
|
|
23
26
|
$: widgetEmailReqMsg = feedbackData.wgEmailReqMsg;
|
|
24
27
|
$: widgetPlaceholder = feedbackData.wgFeedbackPlaceholder;
|
|
25
28
|
$: widgetEmotIconType = feedbackData.wgReactionStyle;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"--
|
|
33
|
-
dislikeDisplay
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"--
|
|
37
|
-
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
$:
|
|
29
|
+
|
|
30
|
+
// Set CSS custom properties only once on mount, then update individually as needed
|
|
31
|
+
// This avoids triggering multiple style recalculations on every reactive update
|
|
32
|
+
onMount(() => {
|
|
33
|
+
const root = document.documentElement.style;
|
|
34
|
+
root.setProperty("--pointerMargin", pointerMargin + "%");
|
|
35
|
+
root.setProperty("--hateDisplay", hateDisplay);
|
|
36
|
+
root.setProperty("--dislikeDisplay", dislikeDisplay);
|
|
37
|
+
root.setProperty("--neutralDisplay", neutralDisplay);
|
|
38
|
+
root.setProperty("--likeDisplay", likeDisplay);
|
|
39
|
+
root.setProperty("--loveDisplay", loveDisplay);
|
|
40
|
+
root.setProperty("--buttonColor", buttonColor);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Update CSS properties only when specific values change
|
|
44
|
+
$: if (typeof window !== 'undefined') {
|
|
45
|
+
document.documentElement.style.setProperty("--pointerMargin", pointerMargin + "%");
|
|
46
|
+
}
|
|
47
|
+
$: if (typeof window !== 'undefined') {
|
|
48
|
+
document.documentElement.style.setProperty("--hateDisplay", hateDisplay);
|
|
49
|
+
document.documentElement.style.setProperty("--dislikeDisplay", dislikeDisplay);
|
|
50
|
+
document.documentElement.style.setProperty("--neutralDisplay", neutralDisplay);
|
|
51
|
+
document.documentElement.style.setProperty("--likeDisplay", likeDisplay);
|
|
52
|
+
document.documentElement.style.setProperty("--loveDisplay", loveDisplay);
|
|
53
|
+
}
|
|
54
|
+
$: if (typeof window !== 'undefined') {
|
|
55
|
+
document.documentElement.style.setProperty("--buttonColor", buttonColor);
|
|
56
|
+
}
|
|
42
57
|
|
|
43
58
|
let count = 0;
|
|
44
|
-
|
|
59
|
+
let buttonState = false;
|
|
60
|
+
let emailError = "";
|
|
45
61
|
let checkTextAreaInterval;
|
|
46
|
-
let checkEmailAreaInterval;
|
|
47
62
|
|
|
48
63
|
export let closeHandler = (
|
|
49
64
|
email,
|
|
@@ -53,13 +68,6 @@
|
|
|
53
68
|
) => {};
|
|
54
69
|
export let closeHandlerBeforeFinishing = (email, comment, reactionType) => {};
|
|
55
70
|
|
|
56
|
-
// const commentButtonDisable = () =>{
|
|
57
|
-
|
|
58
|
-
// let source = document.querySelector(".fsTextArea");
|
|
59
|
-
|
|
60
|
-
// source.addEventListener('propertychange', commentHandler);
|
|
61
|
-
|
|
62
|
-
// }
|
|
63
71
|
const commentHandler = () => {
|
|
64
72
|
let input = document.querySelector(".fsTextArea");
|
|
65
73
|
|
|
@@ -72,27 +80,30 @@
|
|
|
72
80
|
comment = input.value;
|
|
73
81
|
};
|
|
74
82
|
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const emailHandler = () => {
|
|
84
|
-
let input = document.querySelector("#fsEmailTextArea");
|
|
83
|
+
// Ultra-fast email handler - just updates value, no validation during typing
|
|
84
|
+
const emailHandler = (event) => {
|
|
85
|
+
email = event.target.value;
|
|
86
|
+
emailError = ""; // Clear error when user types
|
|
87
|
+
// Enable button if there's any content
|
|
88
|
+
buttonState = email.length > 0;
|
|
89
|
+
};
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
// Validate only when user clicks Send - much better performance
|
|
92
|
+
const validateAndSubmitEmail = () => {
|
|
93
|
+
const trimmedEmail = email.trim();
|
|
94
|
+
|
|
95
|
+
// Quick client-side validation
|
|
96
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
97
|
+
|
|
98
|
+
if (!trimmedEmail || !emailRegex.test(trimmedEmail)) {
|
|
99
|
+
emailError = "Please enter a valid email address";
|
|
100
|
+
buttonState = false;
|
|
101
|
+
return;
|
|
95
102
|
}
|
|
103
|
+
|
|
104
|
+
// Valid - proceed with submission
|
|
105
|
+
emailError = "";
|
|
106
|
+
closeHandler(email, comment, reactionType, questionAnswer);
|
|
96
107
|
};
|
|
97
108
|
|
|
98
109
|
const changeStyle = (prevState) => {
|
|
@@ -179,19 +190,29 @@
|
|
|
179
190
|
clearInterval(checkTextAreaInterval);
|
|
180
191
|
document.querySelector(".fsTextArea").value = "";
|
|
181
192
|
buttonState = false;
|
|
182
|
-
|
|
193
|
+
if (widgetEmailComponentActivation) {
|
|
194
|
+
widgetComponent = state;
|
|
195
|
+
} else {
|
|
196
|
+
closeHandler(email, comment, reactionType, questionAnswer);
|
|
197
|
+
}
|
|
183
198
|
};
|
|
184
199
|
|
|
185
200
|
const openEmailView = (state) => {
|
|
186
201
|
clearInterval(checkTextAreaInterval);
|
|
187
202
|
document.querySelector(".fsAnswerTextArea").value = "";
|
|
188
203
|
buttonState = false;
|
|
189
|
-
|
|
204
|
+
if (widgetEmailComponentActivation) {
|
|
205
|
+
widgetComponent = state;
|
|
206
|
+
} else {
|
|
207
|
+
closeHandler(email, comment, reactionType, questionAnswer);
|
|
208
|
+
}
|
|
190
209
|
};
|
|
191
210
|
|
|
192
211
|
const endEmailInterval = () => {
|
|
193
|
-
|
|
194
|
-
|
|
212
|
+
const el = document.querySelector("#fsEmailTextArea");
|
|
213
|
+
if (el) el.value = "";
|
|
214
|
+
email = "";
|
|
215
|
+
emailError = "";
|
|
195
216
|
};
|
|
196
217
|
</script>
|
|
197
218
|
|
|
@@ -366,7 +387,7 @@
|
|
|
366
387
|
</div>
|
|
367
388
|
</div>
|
|
368
389
|
{:else if widgetComponent === 2 && wgType === 2}
|
|
369
|
-
<div id="fsTxtNps">
|
|
390
|
+
<div id="fsTxtNps">{widgetPlaceholder}</div>
|
|
370
391
|
<div class="fsTextAreaCont-qa-view">
|
|
371
392
|
<textarea
|
|
372
393
|
class="fsTextArea"
|
|
@@ -390,12 +411,16 @@
|
|
|
390
411
|
</div>
|
|
391
412
|
<div id="fsEmailInputCont">
|
|
392
413
|
<input
|
|
393
|
-
type="
|
|
414
|
+
type="email"
|
|
394
415
|
id="fsEmailTextArea"
|
|
395
416
|
placeholder="email@domain.com"
|
|
396
|
-
|
|
417
|
+
autocomplete="email"
|
|
418
|
+
on:input={emailHandler}
|
|
397
419
|
/>
|
|
398
420
|
</div>
|
|
421
|
+
{#if emailError}
|
|
422
|
+
<div class="fsEmailError">{emailError}</div>
|
|
423
|
+
{/if}
|
|
399
424
|
<div class="fsEmailFooter">
|
|
400
425
|
<p
|
|
401
426
|
id="fsSkipText"
|
|
@@ -411,9 +436,7 @@
|
|
|
411
436
|
{:else if buttonState == true}
|
|
412
437
|
<button
|
|
413
438
|
class="fsSendButtonContCommentComp"
|
|
414
|
-
on:click={
|
|
415
|
-
closeHandler(email, comment, reactionType, questionAnswer)}
|
|
416
|
-
on:click={() => endEmailInterval()}
|
|
439
|
+
on:click={validateAndSubmitEmail}
|
|
417
440
|
>
|
|
418
441
|
<p class="fsSendButtonCommentComponent">Send</p>
|
|
419
442
|
</button>
|