feedtack 0.1.0 → 0.2.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/react/index.d.ts +2 -1
- package/dist/react/index.js +177 -114
- package/package.json +2 -2
package/dist/react/index.d.ts
CHANGED
|
@@ -23,8 +23,9 @@ interface FeedtackProviderProps {
|
|
|
23
23
|
classes?: FeedtackClasses;
|
|
24
24
|
sentimentLabels?: FeedtackSentimentLabels;
|
|
25
25
|
onError?: (err: Error) => void;
|
|
26
|
+
disabled?: boolean;
|
|
26
27
|
}
|
|
27
|
-
declare function FeedtackProvider({ children, adapter, currentUser, hotkey, adminOnly, theme, classes, sentimentLabels, onError, }: FeedtackProviderProps): react_jsx_runtime.JSX.Element;
|
|
28
|
+
declare function FeedtackProvider({ children, adapter, currentUser, hotkey, adminOnly, theme, classes, sentimentLabels, onError, disabled, }: FeedtackProviderProps): react_jsx_runtime.JSX.Element;
|
|
28
29
|
|
|
29
30
|
interface FeedtackContextValue {
|
|
30
31
|
activatePinMode: () => void;
|
package/dist/react/index.js
CHANGED
|
@@ -24,16 +24,6 @@ var PIN_PALETTE = [
|
|
|
24
24
|
// pink
|
|
25
25
|
];
|
|
26
26
|
|
|
27
|
-
// src/react/context.ts
|
|
28
|
-
import { createContext, useContext } from "react";
|
|
29
|
-
var FeedtackContext = createContext(null);
|
|
30
|
-
function useFeedtackContext() {
|
|
31
|
-
const ctx = useContext(FeedtackContext);
|
|
32
|
-
if (!ctx)
|
|
33
|
-
throw new Error("useFeedtack must be used inside <FeedtackProvider>");
|
|
34
|
-
return ctx;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
27
|
// src/react/utils.ts
|
|
38
28
|
function generateId() {
|
|
39
29
|
return `ft_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
@@ -55,8 +45,98 @@ function cx(...parts) {
|
|
|
55
45
|
return parts.filter(Boolean).join(" ");
|
|
56
46
|
}
|
|
57
47
|
|
|
58
|
-
// src/react/
|
|
48
|
+
// src/react/CommentForm.tsx
|
|
59
49
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
50
|
+
function CommentForm({
|
|
51
|
+
comment,
|
|
52
|
+
commentError,
|
|
53
|
+
sentiment,
|
|
54
|
+
submitting,
|
|
55
|
+
formPos,
|
|
56
|
+
classes,
|
|
57
|
+
sentimentLabels,
|
|
58
|
+
onCommentChange,
|
|
59
|
+
onSentimentChange,
|
|
60
|
+
onSubmit,
|
|
61
|
+
onCancel
|
|
62
|
+
}) {
|
|
63
|
+
return /* @__PURE__ */ jsxs(
|
|
64
|
+
"div",
|
|
65
|
+
{
|
|
66
|
+
className: cx("feedtack-form", classes.form),
|
|
67
|
+
style: { position: "fixed", ...formPos },
|
|
68
|
+
children: [
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
"textarea",
|
|
71
|
+
{
|
|
72
|
+
className: commentError ? "error" : "",
|
|
73
|
+
placeholder: "What's the issue? (required)",
|
|
74
|
+
value: comment,
|
|
75
|
+
onChange: (e) => onCommentChange(e.target.value),
|
|
76
|
+
ref: (el) => el?.focus()
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
commentError && /* @__PURE__ */ jsx("span", { className: "feedtack-error-msg", children: "Comment is required" }),
|
|
80
|
+
/* @__PURE__ */ jsxs("div", { className: "feedtack-sentiment", children: [
|
|
81
|
+
/* @__PURE__ */ jsx(
|
|
82
|
+
"button",
|
|
83
|
+
{
|
|
84
|
+
type: "button",
|
|
85
|
+
className: sentiment === "satisfied" ? "selected" : "",
|
|
86
|
+
onClick: () => onSentimentChange(sentiment === "satisfied" ? null : "satisfied"),
|
|
87
|
+
children: sentimentLabels.satisfied ?? "\u{1F60A} Satisfied"
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsx(
|
|
91
|
+
"button",
|
|
92
|
+
{
|
|
93
|
+
type: "button",
|
|
94
|
+
className: sentiment === "dissatisfied" ? "selected" : "",
|
|
95
|
+
onClick: () => onSentimentChange(
|
|
96
|
+
sentiment === "dissatisfied" ? null : "dissatisfied"
|
|
97
|
+
),
|
|
98
|
+
children: sentimentLabels.dissatisfied ?? "\u{1F61E} Dissatisfied"
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsxs("div", { className: "feedtack-form-actions", children: [
|
|
103
|
+
/* @__PURE__ */ jsx(
|
|
104
|
+
"button",
|
|
105
|
+
{
|
|
106
|
+
type: "button",
|
|
107
|
+
className: "feedtack-btn-cancel",
|
|
108
|
+
onClick: onCancel,
|
|
109
|
+
children: "Cancel"
|
|
110
|
+
}
|
|
111
|
+
),
|
|
112
|
+
/* @__PURE__ */ jsx(
|
|
113
|
+
"button",
|
|
114
|
+
{
|
|
115
|
+
type: "button",
|
|
116
|
+
className: "feedtack-btn-submit",
|
|
117
|
+
onClick: onSubmit,
|
|
118
|
+
disabled: submitting,
|
|
119
|
+
children: submitting ? "Sending\u2026" : "Submit"
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
] })
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/react/context.ts
|
|
129
|
+
import { createContext, useContext } from "react";
|
|
130
|
+
var FeedtackContext = createContext(null);
|
|
131
|
+
function useFeedtackContext() {
|
|
132
|
+
const ctx = useContext(FeedtackContext);
|
|
133
|
+
if (!ctx)
|
|
134
|
+
throw new Error("useFeedtack must be used inside <FeedtackProvider>");
|
|
135
|
+
return ctx;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/react/ThreadPanel.tsx
|
|
139
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
60
140
|
function ThreadPanel({
|
|
61
141
|
item,
|
|
62
142
|
replyBody,
|
|
@@ -69,26 +149,26 @@ function ThreadPanel({
|
|
|
69
149
|
}) {
|
|
70
150
|
const pin = item.payload.pins[0];
|
|
71
151
|
const pos = getAnchoredPosition(pin.x, pin.y);
|
|
72
|
-
return /* @__PURE__ */
|
|
152
|
+
return /* @__PURE__ */ jsxs2(
|
|
73
153
|
"div",
|
|
74
154
|
{
|
|
75
155
|
className: cx("feedtack-thread", className),
|
|
76
156
|
style: { position: "fixed", ...pos },
|
|
77
157
|
children: [
|
|
78
|
-
/* @__PURE__ */
|
|
79
|
-
/* @__PURE__ */
|
|
80
|
-
item.replies.map((r) => /* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ jsx2("strong", { style: { fontSize: 13 }, children: item.payload.submittedBy.name }),
|
|
159
|
+
/* @__PURE__ */ jsx2("p", { style: { fontSize: 13 }, children: item.payload.comment }),
|
|
160
|
+
item.replies.map((r) => /* @__PURE__ */ jsxs2(
|
|
81
161
|
"div",
|
|
82
162
|
{
|
|
83
163
|
style: { borderTop: "1px solid #f3f4f6", paddingTop: 8 },
|
|
84
164
|
children: [
|
|
85
|
-
/* @__PURE__ */
|
|
86
|
-
/* @__PURE__ */
|
|
165
|
+
/* @__PURE__ */ jsx2("span", { style: { fontSize: 12, fontWeight: 600 }, children: r.author.name }),
|
|
166
|
+
/* @__PURE__ */ jsx2("p", { style: { fontSize: 12 }, children: r.body })
|
|
87
167
|
]
|
|
88
168
|
},
|
|
89
169
|
r.id
|
|
90
170
|
)),
|
|
91
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ jsx2(
|
|
92
172
|
"textarea",
|
|
93
173
|
{
|
|
94
174
|
placeholder: "Reply\u2026",
|
|
@@ -104,8 +184,8 @@ function ThreadPanel({
|
|
|
104
184
|
}
|
|
105
185
|
}
|
|
106
186
|
),
|
|
107
|
-
/* @__PURE__ */
|
|
108
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: 6, flexWrap: "wrap" }, children: [
|
|
188
|
+
/* @__PURE__ */ jsx2(
|
|
109
189
|
"button",
|
|
110
190
|
{
|
|
111
191
|
type: "button",
|
|
@@ -115,7 +195,7 @@ function ThreadPanel({
|
|
|
115
195
|
children: "Reply"
|
|
116
196
|
}
|
|
117
197
|
),
|
|
118
|
-
/* @__PURE__ */
|
|
198
|
+
/* @__PURE__ */ jsx2(
|
|
119
199
|
"button",
|
|
120
200
|
{
|
|
121
201
|
type: "button",
|
|
@@ -125,7 +205,7 @@ function ThreadPanel({
|
|
|
125
205
|
children: "Mark Resolved"
|
|
126
206
|
}
|
|
127
207
|
),
|
|
128
|
-
/* @__PURE__ */
|
|
208
|
+
/* @__PURE__ */ jsx2(
|
|
129
209
|
"button",
|
|
130
210
|
{
|
|
131
211
|
type: "button",
|
|
@@ -135,7 +215,7 @@ function ThreadPanel({
|
|
|
135
215
|
children: "Archive"
|
|
136
216
|
}
|
|
137
217
|
),
|
|
138
|
-
/* @__PURE__ */
|
|
218
|
+
/* @__PURE__ */ jsx2(
|
|
139
219
|
"button",
|
|
140
220
|
{
|
|
141
221
|
type: "button",
|
|
@@ -385,9 +465,10 @@ var FEEDTACK_STYLES = `
|
|
|
385
465
|
`;
|
|
386
466
|
|
|
387
467
|
// src/react/useFeedtackDom.ts
|
|
388
|
-
function useFeedtackDom(theme) {
|
|
468
|
+
function useFeedtackDom(theme, disabled) {
|
|
389
469
|
const rootRef = useRef(null);
|
|
390
470
|
useEffect(() => {
|
|
471
|
+
if (disabled) return;
|
|
391
472
|
if (document.getElementById("feedtack-styles")) return;
|
|
392
473
|
const style = document.createElement("style");
|
|
393
474
|
style.id = "feedtack-styles";
|
|
@@ -396,8 +477,9 @@ function useFeedtackDom(theme) {
|
|
|
396
477
|
return () => {
|
|
397
478
|
style.remove();
|
|
398
479
|
};
|
|
399
|
-
}, []);
|
|
480
|
+
}, [disabled]);
|
|
400
481
|
useEffect(() => {
|
|
482
|
+
if (disabled) return;
|
|
401
483
|
const root = document.createElement("div");
|
|
402
484
|
root.id = "feedtack-root";
|
|
403
485
|
document.body.appendChild(root);
|
|
@@ -405,21 +487,22 @@ function useFeedtackDom(theme) {
|
|
|
405
487
|
return () => {
|
|
406
488
|
root.remove();
|
|
407
489
|
};
|
|
408
|
-
}, []);
|
|
490
|
+
}, [disabled]);
|
|
409
491
|
useEffect(() => {
|
|
492
|
+
if (disabled) return;
|
|
410
493
|
const root = document.getElementById("feedtack-root");
|
|
411
494
|
if (!root || !theme) return;
|
|
412
495
|
const tokens = themeToCSS(theme);
|
|
413
496
|
for (const [k, v] of Object.entries(tokens)) {
|
|
414
497
|
root.style.setProperty(k, v);
|
|
415
498
|
}
|
|
416
|
-
}, [theme]);
|
|
499
|
+
}, [theme, disabled]);
|
|
417
500
|
return rootRef;
|
|
418
501
|
}
|
|
419
502
|
|
|
420
503
|
// src/react/usePinMode.ts
|
|
421
504
|
import { useCallback, useEffect as useEffect2, useState } from "react";
|
|
422
|
-
function usePinMode({ hotkey, onDeactivate }) {
|
|
505
|
+
function usePinMode({ hotkey, onDeactivate, disabled }) {
|
|
423
506
|
const [isActive, setIsActive] = useState(false);
|
|
424
507
|
const [pendingPins, setPendingPins] = useState([]);
|
|
425
508
|
const [selectedColor, setSelectedColor] = useState(PIN_PALETTE[0]);
|
|
@@ -440,6 +523,7 @@ function usePinMode({ hotkey, onDeactivate }) {
|
|
|
440
523
|
return () => document.documentElement.classList.remove("feedtack-crosshair");
|
|
441
524
|
}, [isActive]);
|
|
442
525
|
useEffect2(() => {
|
|
526
|
+
if (disabled) return;
|
|
443
527
|
const handler = (e) => {
|
|
444
528
|
if (e.key === hotkey.toUpperCase() && e.shiftKey) {
|
|
445
529
|
setIsActive((prev) => !prev);
|
|
@@ -458,7 +542,7 @@ function usePinMode({ hotkey, onDeactivate }) {
|
|
|
458
542
|
};
|
|
459
543
|
window.addEventListener("keydown", handler);
|
|
460
544
|
return () => window.removeEventListener("keydown", handler);
|
|
461
|
-
}, [hotkey, deactivate, isActive]);
|
|
545
|
+
}, [hotkey, deactivate, isActive, disabled]);
|
|
462
546
|
const handlePageClick = useCallback(
|
|
463
547
|
(e) => {
|
|
464
548
|
if (!isActive) return;
|
|
@@ -480,9 +564,10 @@ function usePinMode({ hotkey, onDeactivate }) {
|
|
|
480
564
|
[isActive, selectedColor]
|
|
481
565
|
);
|
|
482
566
|
useEffect2(() => {
|
|
567
|
+
if (disabled) return;
|
|
483
568
|
document.addEventListener("click", handlePageClick, true);
|
|
484
569
|
return () => document.removeEventListener("click", handlePageClick, true);
|
|
485
|
-
}, [handlePageClick]);
|
|
570
|
+
}, [handlePageClick, disabled]);
|
|
486
571
|
return {
|
|
487
572
|
isActive,
|
|
488
573
|
activate,
|
|
@@ -500,9 +585,30 @@ function useFeedtackState({
|
|
|
500
585
|
currentUser,
|
|
501
586
|
hotkey,
|
|
502
587
|
theme,
|
|
503
|
-
onError
|
|
588
|
+
onError,
|
|
589
|
+
disabled
|
|
504
590
|
}) {
|
|
505
|
-
useFeedtackDom(theme);
|
|
591
|
+
useFeedtackDom(theme, disabled);
|
|
592
|
+
const [pathname, setPathname] = useState2(() => window.location.pathname);
|
|
593
|
+
useEffect3(() => {
|
|
594
|
+
const update = () => setPathname(window.location.pathname);
|
|
595
|
+
const origPush = history.pushState.bind(history);
|
|
596
|
+
const origReplace = history.replaceState.bind(history);
|
|
597
|
+
history.pushState = (...args) => {
|
|
598
|
+
origPush(...args);
|
|
599
|
+
update();
|
|
600
|
+
};
|
|
601
|
+
history.replaceState = (...args) => {
|
|
602
|
+
origReplace(...args);
|
|
603
|
+
update();
|
|
604
|
+
};
|
|
605
|
+
window.addEventListener("popstate", update);
|
|
606
|
+
return () => {
|
|
607
|
+
window.removeEventListener("popstate", update);
|
|
608
|
+
history.pushState = origPush;
|
|
609
|
+
history.replaceState = origReplace;
|
|
610
|
+
};
|
|
611
|
+
}, []);
|
|
506
612
|
const [comment, setComment] = useState2("");
|
|
507
613
|
const [sentiment, setSentiment] = useState2(null);
|
|
508
614
|
const [commentError, setCommentError] = useState2(false);
|
|
@@ -518,6 +624,7 @@ function useFeedtackState({
|
|
|
518
624
|
}, []);
|
|
519
625
|
const pinMode = usePinMode({
|
|
520
626
|
hotkey,
|
|
627
|
+
disabled,
|
|
521
628
|
onDeactivate: () => {
|
|
522
629
|
resetForm();
|
|
523
630
|
setOpenThreadId(null);
|
|
@@ -525,8 +632,8 @@ function useFeedtackState({
|
|
|
525
632
|
});
|
|
526
633
|
useEffect3(() => {
|
|
527
634
|
setLoading(true);
|
|
528
|
-
adapter.loadFeedback({ pathname
|
|
529
|
-
}, [adapter, onError]);
|
|
635
|
+
adapter.loadFeedback({ pathname }).then(setFeedbackItems).catch((err) => onError?.(err)).finally(() => setLoading(false));
|
|
636
|
+
}, [adapter, onError, pathname]);
|
|
530
637
|
const updateItem = (id, fn) => setFeedbackItems(
|
|
531
638
|
(prev) => prev.map((i) => i.payload.id === id ? fn(i) : i)
|
|
532
639
|
);
|
|
@@ -635,6 +742,7 @@ function useFeedtackState({
|
|
|
635
742
|
commentError,
|
|
636
743
|
setCommentError,
|
|
637
744
|
submitting,
|
|
745
|
+
pathname,
|
|
638
746
|
feedbackItems,
|
|
639
747
|
loading,
|
|
640
748
|
openThreadId,
|
|
@@ -651,7 +759,7 @@ function useFeedtackState({
|
|
|
651
759
|
}
|
|
652
760
|
|
|
653
761
|
// src/react/FeedtackProvider.tsx
|
|
654
|
-
import { jsx as
|
|
762
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
655
763
|
function FeedtackProvider({
|
|
656
764
|
children,
|
|
657
765
|
adapter,
|
|
@@ -661,30 +769,34 @@ function FeedtackProvider({
|
|
|
661
769
|
theme,
|
|
662
770
|
classes = {},
|
|
663
771
|
sentimentLabels = {},
|
|
664
|
-
onError
|
|
772
|
+
onError,
|
|
773
|
+
disabled = false
|
|
665
774
|
}) {
|
|
666
775
|
const state = useFeedtackState({
|
|
667
776
|
adapter,
|
|
668
777
|
currentUser,
|
|
669
778
|
hotkey,
|
|
670
779
|
theme,
|
|
671
|
-
onError
|
|
780
|
+
onError,
|
|
781
|
+
disabled
|
|
672
782
|
});
|
|
673
783
|
const firstPin = state.pendingPins[0];
|
|
674
784
|
const formPos = firstPin ? getAnchoredPosition(firstPin.x, firstPin.y) : {};
|
|
675
785
|
const showButton = !adminOnly || currentUser.role === "admin";
|
|
676
786
|
const openItem = state.openThreadId ? state.feedbackItems.find((i) => i.payload.id === state.openThreadId) : null;
|
|
677
|
-
return /* @__PURE__ */
|
|
787
|
+
return /* @__PURE__ */ jsxs3(
|
|
678
788
|
FeedtackContext.Provider,
|
|
679
789
|
{
|
|
680
790
|
value: {
|
|
681
|
-
activatePinMode:
|
|
682
|
-
|
|
683
|
-
|
|
791
|
+
activatePinMode: disabled ? () => {
|
|
792
|
+
} : state.activatePinMode,
|
|
793
|
+
deactivatePinMode: disabled ? () => {
|
|
794
|
+
} : state.deactivatePinMode,
|
|
795
|
+
isPinModeActive: disabled ? false : state.isPinModeActive
|
|
684
796
|
},
|
|
685
797
|
children: [
|
|
686
798
|
children,
|
|
687
|
-
showButton && /* @__PURE__ */
|
|
799
|
+
!disabled && showButton && /* @__PURE__ */ jsxs3(
|
|
688
800
|
"button",
|
|
689
801
|
{
|
|
690
802
|
type: "button",
|
|
@@ -702,7 +814,7 @@ function FeedtackProvider({
|
|
|
702
814
|
]
|
|
703
815
|
}
|
|
704
816
|
),
|
|
705
|
-
state.isPinModeActive && /* @__PURE__ */
|
|
817
|
+
state.isPinModeActive && /* @__PURE__ */ jsx3("div", { className: cx("feedtack-color-picker", classes.colorPicker), children: PIN_PALETTE.map((color) => /* @__PURE__ */ jsx3(
|
|
706
818
|
"button",
|
|
707
819
|
{
|
|
708
820
|
type: "button",
|
|
@@ -716,7 +828,7 @@ function FeedtackProvider({
|
|
|
716
828
|
},
|
|
717
829
|
color
|
|
718
830
|
)) }),
|
|
719
|
-
state.pendingPins.map((pin) => /* @__PURE__ */
|
|
831
|
+
state.pendingPins.map((pin) => /* @__PURE__ */ jsx3(
|
|
720
832
|
"div",
|
|
721
833
|
{
|
|
722
834
|
className: cx("feedtack-pin-marker", classes.pinMarker),
|
|
@@ -729,77 +841,28 @@ function FeedtackProvider({
|
|
|
729
841
|
},
|
|
730
842
|
`${pin.x}-${pin.y}-${pin.color}`
|
|
731
843
|
)),
|
|
732
|
-
state.showForm && /* @__PURE__ */
|
|
733
|
-
|
|
844
|
+
state.showForm && /* @__PURE__ */ jsx3(
|
|
845
|
+
CommentForm,
|
|
734
846
|
{
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
}
|
|
750
|
-
),
|
|
751
|
-
state.commentError && /* @__PURE__ */ jsx2("span", { className: "feedtack-error-msg", children: "Comment is required" }),
|
|
752
|
-
/* @__PURE__ */ jsxs2("div", { className: "feedtack-sentiment", children: [
|
|
753
|
-
/* @__PURE__ */ jsx2(
|
|
754
|
-
"button",
|
|
755
|
-
{
|
|
756
|
-
type: "button",
|
|
757
|
-
className: state.sentiment === "satisfied" ? "selected" : "",
|
|
758
|
-
onClick: () => state.setSentiment(
|
|
759
|
-
state.sentiment === "satisfied" ? null : "satisfied"
|
|
760
|
-
),
|
|
761
|
-
children: sentimentLabels.satisfied ?? "\u{1F60A} Satisfied"
|
|
762
|
-
}
|
|
763
|
-
),
|
|
764
|
-
/* @__PURE__ */ jsx2(
|
|
765
|
-
"button",
|
|
766
|
-
{
|
|
767
|
-
type: "button",
|
|
768
|
-
className: state.sentiment === "dissatisfied" ? "selected" : "",
|
|
769
|
-
onClick: () => state.setSentiment(
|
|
770
|
-
state.sentiment === "dissatisfied" ? null : "dissatisfied"
|
|
771
|
-
),
|
|
772
|
-
children: sentimentLabels.dissatisfied ?? "\u{1F61E} Dissatisfied"
|
|
773
|
-
}
|
|
774
|
-
)
|
|
775
|
-
] }),
|
|
776
|
-
/* @__PURE__ */ jsxs2("div", { className: "feedtack-form-actions", children: [
|
|
777
|
-
/* @__PURE__ */ jsx2(
|
|
778
|
-
"button",
|
|
779
|
-
{
|
|
780
|
-
type: "button",
|
|
781
|
-
className: "feedtack-btn-cancel",
|
|
782
|
-
onClick: state.deactivatePinMode,
|
|
783
|
-
children: "Cancel"
|
|
784
|
-
}
|
|
785
|
-
),
|
|
786
|
-
/* @__PURE__ */ jsx2(
|
|
787
|
-
"button",
|
|
788
|
-
{
|
|
789
|
-
type: "button",
|
|
790
|
-
className: "feedtack-btn-submit",
|
|
791
|
-
onClick: state.handleSubmit,
|
|
792
|
-
disabled: state.submitting,
|
|
793
|
-
children: state.submitting ? "Sending\u2026" : "Submit"
|
|
794
|
-
}
|
|
795
|
-
)
|
|
796
|
-
] })
|
|
797
|
-
]
|
|
847
|
+
comment: state.comment,
|
|
848
|
+
commentError: state.commentError,
|
|
849
|
+
sentiment: state.sentiment,
|
|
850
|
+
submitting: state.submitting,
|
|
851
|
+
formPos,
|
|
852
|
+
classes,
|
|
853
|
+
sentimentLabels,
|
|
854
|
+
onCommentChange: (v) => {
|
|
855
|
+
state.setComment(v);
|
|
856
|
+
state.setCommentError(false);
|
|
857
|
+
},
|
|
858
|
+
onSentimentChange: state.setSentiment,
|
|
859
|
+
onSubmit: state.handleSubmit,
|
|
860
|
+
onCancel: state.deactivatePinMode
|
|
798
861
|
}
|
|
799
862
|
),
|
|
800
|
-
!state.loading && state.feedbackItems.filter((item) => !state.isArchivedForUser(item)).map((item) => {
|
|
863
|
+
!state.loading && state.feedbackItems.filter((item) => item.payload.page.pathname === state.pathname).filter((item) => !state.isArchivedForUser(item)).map((item) => {
|
|
801
864
|
const pin = item.payload.pins[0];
|
|
802
|
-
return /* @__PURE__ */
|
|
865
|
+
return /* @__PURE__ */ jsx3(
|
|
803
866
|
"button",
|
|
804
867
|
{
|
|
805
868
|
type: "button",
|
|
@@ -814,12 +877,12 @@ function FeedtackProvider({
|
|
|
814
877
|
onClick: () => state.setOpenThreadId(
|
|
815
878
|
state.openThreadId === item.payload.id ? null : item.payload.id
|
|
816
879
|
),
|
|
817
|
-
children: state.hasUnread(item) && /* @__PURE__ */
|
|
880
|
+
children: state.hasUnread(item) && /* @__PURE__ */ jsx3("div", { className: "feedtack-pin-badge" })
|
|
818
881
|
},
|
|
819
882
|
item.payload.id
|
|
820
883
|
);
|
|
821
884
|
}),
|
|
822
|
-
openItem && /* @__PURE__ */
|
|
885
|
+
openItem && /* @__PURE__ */ jsx3(
|
|
823
886
|
ThreadPanel,
|
|
824
887
|
{
|
|
825
888
|
item: openItem,
|
|
@@ -832,7 +895,7 @@ function FeedtackProvider({
|
|
|
832
895
|
className: classes.thread
|
|
833
896
|
}
|
|
834
897
|
),
|
|
835
|
-
state.loading && /* @__PURE__ */
|
|
898
|
+
state.loading && /* @__PURE__ */ jsx3("div", { className: "feedtack-loading", children: "Loading feedback\u2026" })
|
|
836
899
|
]
|
|
837
900
|
}
|
|
838
901
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feedtack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Click anywhere. Drop a pin. Get a payload a developer can act on.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"test:watch": "vitest",
|
|
31
31
|
"lint": "biome check src/",
|
|
32
32
|
"lint:fix": "biome check --fix src/",
|
|
33
|
-
"release": "release-it",
|
|
33
|
+
"release": "release-it --ci",
|
|
34
34
|
"prepublishOnly": "pnpm test && pnpm build",
|
|
35
35
|
"prepare": "husky"
|
|
36
36
|
},
|