feedtack 0.0.1 → 0.0.3
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.
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
// src/types/payload.ts
|
|
2
2
|
var SCHEMA_VERSION = "1.0.0";
|
|
3
3
|
|
|
4
|
+
// src/types/theme.ts
|
|
5
|
+
function themeToCSS(theme) {
|
|
6
|
+
const map = {};
|
|
7
|
+
if (theme.primary) map["--ft-primary"] = theme.primary;
|
|
8
|
+
if (theme.background) map["--ft-bg"] = theme.background;
|
|
9
|
+
if (theme.surface) map["--ft-surface"] = theme.surface;
|
|
10
|
+
if (theme.text) map["--ft-text"] = theme.text;
|
|
11
|
+
if (theme.textMuted) map["--ft-text-muted"] = theme.textMuted;
|
|
12
|
+
if (theme.border) map["--ft-border"] = theme.border;
|
|
13
|
+
if (theme.radius) map["--ft-radius"] = theme.radius;
|
|
14
|
+
if (theme.badge) map["--ft-badge"] = theme.badge;
|
|
15
|
+
return map;
|
|
16
|
+
}
|
|
17
|
+
|
|
4
18
|
// src/capture/target.ts
|
|
5
19
|
function getCSSSelector(element) {
|
|
6
20
|
const parts = [];
|
|
@@ -96,6 +110,7 @@ function getPinCoords(event) {
|
|
|
96
110
|
|
|
97
111
|
export {
|
|
98
112
|
SCHEMA_VERSION,
|
|
113
|
+
themeToCSS,
|
|
99
114
|
getCSSSelector,
|
|
100
115
|
getTargetMeta,
|
|
101
116
|
getViewportMeta,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FeedtackAdapter, a as FeedtackPayload, b as FeedtackReply, c as FeedtackResolution, d as FeedtackFilter, e as FeedbackItem, f as FeedtackPinTarget, g as FeedtackDeviceMeta, h as FeedtackPageMeta, i as FeedtackViewportMeta } from './
|
|
2
|
-
export { j as FeedtackArchive, k as FeedtackBoundingRect, l as FeedtackPin, m as FeedtackSentiment, n as FeedtackUser, S as SCHEMA_VERSION } from './
|
|
1
|
+
import { F as FeedtackAdapter, a as FeedtackPayload, b as FeedtackReply, c as FeedtackResolution, d as FeedtackFilter, e as FeedbackItem, f as FeedtackPinTarget, g as FeedtackDeviceMeta, h as FeedtackPageMeta, i as FeedtackViewportMeta } from './theme-CHGvGcG5.js';
|
|
2
|
+
export { j as FeedtackArchive, k as FeedtackBoundingRect, l as FeedtackPin, m as FeedtackSentiment, n as FeedtackTheme, o as FeedtackUser, S as SCHEMA_VERSION, t as themeToCSS } from './theme-CHGvGcG5.js';
|
|
3
3
|
|
|
4
4
|
/** Development adapter — logs all operations to the browser console */
|
|
5
5
|
declare class ConsoleAdapter implements FeedtackAdapter {
|
package/dist/index.js
CHANGED
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
getPageMeta,
|
|
6
6
|
getPinCoords,
|
|
7
7
|
getTargetMeta,
|
|
8
|
-
getViewportMeta
|
|
9
|
-
|
|
8
|
+
getViewportMeta,
|
|
9
|
+
themeToCSS
|
|
10
|
+
} from "./chunk-NOFOQJHM.js";
|
|
10
11
|
|
|
11
12
|
// src/adapters/ConsoleAdapter.ts
|
|
12
13
|
var ConsoleAdapter = class {
|
|
@@ -76,5 +77,6 @@ export {
|
|
|
76
77
|
getPageMeta,
|
|
77
78
|
getPinCoords,
|
|
78
79
|
getTargetMeta,
|
|
79
|
-
getViewportMeta
|
|
80
|
+
getViewportMeta,
|
|
81
|
+
themeToCSS
|
|
80
82
|
};
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { F as FeedtackAdapter,
|
|
3
|
+
import { F as FeedtackAdapter, o as FeedtackUser, n as FeedtackTheme } from '../theme-CHGvGcG5.js';
|
|
4
4
|
|
|
5
|
+
interface FeedtackClasses {
|
|
6
|
+
/** Class added to the activation button */
|
|
7
|
+
button?: string;
|
|
8
|
+
/** Class added to the comment form panel */
|
|
9
|
+
form?: string;
|
|
10
|
+
/** Class added to the thread/reply panel */
|
|
11
|
+
thread?: string;
|
|
12
|
+
/** Class added to the color picker row */
|
|
13
|
+
colorPicker?: string;
|
|
14
|
+
/** Class added to each pin marker */
|
|
15
|
+
pinMarker?: string;
|
|
16
|
+
}
|
|
17
|
+
interface FeedtackSentimentLabels {
|
|
18
|
+
satisfied?: React.ReactNode;
|
|
19
|
+
dissatisfied?: React.ReactNode;
|
|
20
|
+
}
|
|
5
21
|
interface FeedtackProviderProps {
|
|
6
22
|
children: React.ReactNode;
|
|
7
23
|
adapter: FeedtackAdapter;
|
|
@@ -10,9 +26,15 @@ interface FeedtackProviderProps {
|
|
|
10
26
|
hotkey?: string;
|
|
11
27
|
/** Only show the activation button for users whose role is in this list */
|
|
12
28
|
adminOnly?: boolean;
|
|
29
|
+
/** CSS token overrides for brand alignment */
|
|
30
|
+
theme?: FeedtackTheme;
|
|
31
|
+
/** Additional class names for individual feedtack elements */
|
|
32
|
+
classes?: FeedtackClasses;
|
|
33
|
+
/** Custom labels/content for sentiment toggle buttons */
|
|
34
|
+
sentimentLabels?: FeedtackSentimentLabels;
|
|
13
35
|
onError?: (err: Error) => void;
|
|
14
36
|
}
|
|
15
|
-
declare function FeedtackProvider({ children, adapter, currentUser, hotkey, adminOnly, onError }: FeedtackProviderProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
declare function FeedtackProvider({ children, adapter, currentUser, hotkey, adminOnly, theme, classes, sentimentLabels, onError }: FeedtackProviderProps): react_jsx_runtime.JSX.Element;
|
|
16
38
|
|
|
17
39
|
interface FeedtackContextValue {
|
|
18
40
|
activatePinMode: () => void;
|
|
@@ -23,4 +45,4 @@ interface FeedtackContextValue {
|
|
|
23
45
|
/** Hook for host app to programmatically control feedtack */
|
|
24
46
|
declare function useFeedtack(): FeedtackContextValue;
|
|
25
47
|
|
|
26
|
-
export { FeedtackProvider, useFeedtack };
|
|
48
|
+
export { type FeedtackClasses, FeedtackProvider, type FeedtackProviderProps, type FeedtackSentimentLabels, useFeedtack };
|
package/dist/react/index.js
CHANGED
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
getPageMeta,
|
|
5
5
|
getPinCoords,
|
|
6
6
|
getTargetMeta,
|
|
7
|
-
getViewportMeta
|
|
8
|
-
|
|
7
|
+
getViewportMeta,
|
|
8
|
+
themeToCSS
|
|
9
|
+
} from "../chunk-NOFOQJHM.js";
|
|
9
10
|
|
|
10
11
|
// src/react/FeedtackProvider.tsx
|
|
11
12
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -20,6 +21,20 @@ function useFeedtackContext() {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
// src/ui/styles.ts
|
|
24
|
+
var FEEDTACK_DEFAULT_TOKENS = `
|
|
25
|
+
#feedtack-root {
|
|
26
|
+
--ft-primary: #2563eb;
|
|
27
|
+
--ft-primary-hover: #1d4ed8;
|
|
28
|
+
--ft-bg: #ffffff;
|
|
29
|
+
--ft-surface: #f9fafb;
|
|
30
|
+
--ft-text: #111827;
|
|
31
|
+
--ft-text-muted: #6b7280;
|
|
32
|
+
--ft-border: #e5e7eb;
|
|
33
|
+
--ft-radius: 8px;
|
|
34
|
+
--ft-error: #ef4444;
|
|
35
|
+
--ft-badge: #f59e0b;
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
23
38
|
var FEEDTACK_STYLES = `
|
|
24
39
|
#feedtack-root * {
|
|
25
40
|
box-sizing: border-box;
|
|
@@ -34,10 +49,10 @@ var FEEDTACK_STYLES = `
|
|
|
34
49
|
bottom: 24px;
|
|
35
50
|
right: 24px;
|
|
36
51
|
z-index: 2147483640;
|
|
37
|
-
background:
|
|
38
|
-
color:
|
|
52
|
+
background: var(--ft-text);
|
|
53
|
+
color: var(--ft-bg);
|
|
39
54
|
border: none;
|
|
40
|
-
border-radius:
|
|
55
|
+
border-radius: var(--ft-radius);
|
|
41
56
|
padding: 8px 14px;
|
|
42
57
|
font-size: 13px;
|
|
43
58
|
font-weight: 500;
|
|
@@ -50,11 +65,11 @@ var FEEDTACK_STYLES = `
|
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
.feedtack-btn:hover {
|
|
53
|
-
|
|
68
|
+
opacity: 0.85;
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
.feedtack-btn.active {
|
|
57
|
-
background:
|
|
72
|
+
background: var(--ft-primary);
|
|
58
73
|
}
|
|
59
74
|
|
|
60
75
|
.feedtack-crosshair * {
|
|
@@ -80,17 +95,17 @@ var FEEDTACK_STYLES = `
|
|
|
80
95
|
right: -4px;
|
|
81
96
|
width: 10px;
|
|
82
97
|
height: 10px;
|
|
83
|
-
background:
|
|
98
|
+
background: var(--ft-badge);
|
|
84
99
|
border-radius: 50%;
|
|
85
|
-
border: 1.5px solid
|
|
100
|
+
border: 1.5px solid var(--ft-bg);
|
|
86
101
|
}
|
|
87
102
|
|
|
88
103
|
.feedtack-color-picker {
|
|
89
104
|
display: flex;
|
|
90
105
|
gap: 6px;
|
|
91
106
|
padding: 8px;
|
|
92
|
-
background:
|
|
93
|
-
border-radius:
|
|
107
|
+
background: var(--ft-bg) !important;
|
|
108
|
+
border-radius: var(--ft-radius);
|
|
94
109
|
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
95
110
|
position: fixed;
|
|
96
111
|
bottom: 72px;
|
|
@@ -108,15 +123,15 @@ var FEEDTACK_STYLES = `
|
|
|
108
123
|
}
|
|
109
124
|
|
|
110
125
|
.feedtack-color-swatch.selected {
|
|
111
|
-
border-color:
|
|
126
|
+
border-color: var(--ft-text);
|
|
112
127
|
transform: scale(1.15);
|
|
113
128
|
}
|
|
114
129
|
|
|
115
130
|
.feedtack-form {
|
|
116
131
|
position: absolute;
|
|
117
132
|
z-index: 2147483642;
|
|
118
|
-
background:
|
|
119
|
-
border-radius:
|
|
133
|
+
background: var(--ft-bg) !important;
|
|
134
|
+
border-radius: calc(var(--ft-radius) + 2px);
|
|
120
135
|
box-shadow: 0 4px 20px rgba(0,0,0,0.18);
|
|
121
136
|
padding: 16px;
|
|
122
137
|
width: 280px;
|
|
@@ -127,26 +142,28 @@ var FEEDTACK_STYLES = `
|
|
|
127
142
|
|
|
128
143
|
.feedtack-form textarea {
|
|
129
144
|
width: 100%;
|
|
130
|
-
border: 1.5px solid
|
|
131
|
-
border-radius:
|
|
145
|
+
border: 1.5px solid var(--ft-border);
|
|
146
|
+
border-radius: var(--ft-radius);
|
|
132
147
|
padding: 8px;
|
|
133
148
|
font-size: 13px;
|
|
134
149
|
resize: vertical;
|
|
135
150
|
min-height: 80px;
|
|
136
151
|
outline: none;
|
|
152
|
+
background: var(--ft-surface);
|
|
153
|
+
color: var(--ft-text);
|
|
137
154
|
}
|
|
138
155
|
|
|
139
156
|
.feedtack-form textarea:focus {
|
|
140
|
-
border-color:
|
|
157
|
+
border-color: var(--ft-primary);
|
|
141
158
|
}
|
|
142
159
|
|
|
143
160
|
.feedtack-form textarea.error {
|
|
144
|
-
border-color:
|
|
161
|
+
border-color: var(--ft-error);
|
|
145
162
|
}
|
|
146
163
|
|
|
147
164
|
.feedtack-error-msg {
|
|
148
165
|
font-size: 12px;
|
|
149
|
-
color:
|
|
166
|
+
color: var(--ft-error);
|
|
150
167
|
}
|
|
151
168
|
|
|
152
169
|
.feedtack-sentiment {
|
|
@@ -157,18 +174,19 @@ var FEEDTACK_STYLES = `
|
|
|
157
174
|
.feedtack-sentiment button {
|
|
158
175
|
flex: 1;
|
|
159
176
|
padding: 6px 10px;
|
|
160
|
-
border: 1.5px solid
|
|
161
|
-
border-radius:
|
|
162
|
-
background:
|
|
177
|
+
border: 1.5px solid var(--ft-border);
|
|
178
|
+
border-radius: var(--ft-radius);
|
|
179
|
+
background: var(--ft-bg);
|
|
180
|
+
color: var(--ft-text);
|
|
163
181
|
font-size: 12px;
|
|
164
182
|
cursor: pointer;
|
|
165
183
|
transition: all 0.1s;
|
|
166
184
|
}
|
|
167
185
|
|
|
168
186
|
.feedtack-sentiment button.selected {
|
|
169
|
-
border-color:
|
|
170
|
-
background:
|
|
171
|
-
color:
|
|
187
|
+
border-color: var(--ft-primary);
|
|
188
|
+
background: var(--ft-surface);
|
|
189
|
+
color: var(--ft-primary);
|
|
172
190
|
}
|
|
173
191
|
|
|
174
192
|
.feedtack-form-actions {
|
|
@@ -179,9 +197,10 @@ var FEEDTACK_STYLES = `
|
|
|
179
197
|
|
|
180
198
|
.feedtack-btn-cancel {
|
|
181
199
|
padding: 6px 12px;
|
|
182
|
-
border: 1.5px solid
|
|
183
|
-
border-radius:
|
|
184
|
-
background:
|
|
200
|
+
border: 1.5px solid var(--ft-border);
|
|
201
|
+
border-radius: var(--ft-radius);
|
|
202
|
+
background: var(--ft-bg);
|
|
203
|
+
color: var(--ft-text);
|
|
185
204
|
font-size: 13px;
|
|
186
205
|
cursor: pointer;
|
|
187
206
|
}
|
|
@@ -189,8 +208,8 @@ var FEEDTACK_STYLES = `
|
|
|
189
208
|
.feedtack-btn-submit {
|
|
190
209
|
padding: 6px 12px;
|
|
191
210
|
border: none;
|
|
192
|
-
border-radius:
|
|
193
|
-
background:
|
|
211
|
+
border-radius: var(--ft-radius);
|
|
212
|
+
background: var(--ft-primary);
|
|
194
213
|
color: #fff;
|
|
195
214
|
font-size: 13px;
|
|
196
215
|
font-weight: 500;
|
|
@@ -205,8 +224,8 @@ var FEEDTACK_STYLES = `
|
|
|
205
224
|
.feedtack-thread {
|
|
206
225
|
position: absolute;
|
|
207
226
|
z-index: 2147483642;
|
|
208
|
-
background:
|
|
209
|
-
border-radius:
|
|
227
|
+
background: var(--ft-bg) !important;
|
|
228
|
+
border-radius: calc(var(--ft-radius) + 2px);
|
|
210
229
|
box-shadow: 0 4px 20px rgba(0,0,0,0.18);
|
|
211
230
|
padding: 16px;
|
|
212
231
|
width: 300px;
|
|
@@ -222,7 +241,7 @@ var FEEDTACK_STYLES = `
|
|
|
222
241
|
bottom: 70px;
|
|
223
242
|
right: 24px;
|
|
224
243
|
font-size: 12px;
|
|
225
|
-
color:
|
|
244
|
+
color: var(--ft-text-muted);
|
|
226
245
|
z-index: 2147483640;
|
|
227
246
|
}
|
|
228
247
|
`;
|
|
@@ -262,7 +281,7 @@ function getAnchoredPosition(x, y) {
|
|
|
262
281
|
const bottom = clientY > vh - EDGE ? vh - clientY + FORM_HEIGHT : void 0;
|
|
263
282
|
return { left, right, top, bottom };
|
|
264
283
|
}
|
|
265
|
-
function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminOnly = false, onError }) {
|
|
284
|
+
function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminOnly = false, theme, classes = {}, sentimentLabels = {}, onError }) {
|
|
266
285
|
const [isPinModeActive, setIsPinModeActive] = useState(false);
|
|
267
286
|
const [pendingPins, setPendingPins] = useState([]);
|
|
268
287
|
const [selectedColor, setSelectedColor] = useState(PIN_PALETTE[0]);
|
|
@@ -280,7 +299,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
280
299
|
if (document.getElementById("feedtack-styles")) return;
|
|
281
300
|
const style = document.createElement("style");
|
|
282
301
|
style.id = "feedtack-styles";
|
|
283
|
-
style.textContent = FEEDTACK_STYLES;
|
|
302
|
+
style.textContent = FEEDTACK_DEFAULT_TOKENS + FEEDTACK_STYLES;
|
|
284
303
|
document.head.appendChild(style);
|
|
285
304
|
return () => {
|
|
286
305
|
style.remove();
|
|
@@ -295,6 +314,12 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
295
314
|
root.remove();
|
|
296
315
|
};
|
|
297
316
|
}, []);
|
|
317
|
+
useEffect(() => {
|
|
318
|
+
const root = document.getElementById("feedtack-root");
|
|
319
|
+
if (!root || !theme) return;
|
|
320
|
+
const tokens = themeToCSS(theme);
|
|
321
|
+
Object.entries(tokens).forEach(([k, v]) => root.style.setProperty(k, v));
|
|
322
|
+
}, [theme]);
|
|
298
323
|
useEffect(() => {
|
|
299
324
|
setLoading(true);
|
|
300
325
|
adapter.loadFeedback({ pathname: window.location.pathname }).then(setFeedbackItems).catch((err) => onError?.(err)).finally(() => setLoading(false));
|
|
@@ -423,7 +448,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
423
448
|
showButton && /* @__PURE__ */ jsxs(
|
|
424
449
|
"button",
|
|
425
450
|
{
|
|
426
|
-
className: `feedtack-btn${isPinModeActive ? " active" : ""}`,
|
|
451
|
+
className: `feedtack-btn${isPinModeActive ? " active" : ""}${classes.button ? ` ${classes.button}` : ""}`,
|
|
427
452
|
onClick: () => isPinModeActive ? deactivatePinMode() : activatePinMode(),
|
|
428
453
|
title: "Toggle feedback pin mode",
|
|
429
454
|
children: [
|
|
@@ -433,7 +458,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
433
458
|
]
|
|
434
459
|
}
|
|
435
460
|
),
|
|
436
|
-
isPinModeActive && /* @__PURE__ */ jsx("div", { className:
|
|
461
|
+
isPinModeActive && /* @__PURE__ */ jsx("div", { className: `feedtack-color-picker${classes.colorPicker ? ` ${classes.colorPicker}` : ""}`, children: PIN_PALETTE.map((color) => /* @__PURE__ */ jsx(
|
|
437
462
|
"button",
|
|
438
463
|
{
|
|
439
464
|
className: `feedtack-color-swatch${selectedColor === color ? " selected" : ""}`,
|
|
@@ -446,7 +471,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
446
471
|
pendingPins.map((pin, i) => /* @__PURE__ */ jsx(
|
|
447
472
|
"div",
|
|
448
473
|
{
|
|
449
|
-
className:
|
|
474
|
+
className: `feedtack-pin-marker${classes.pinMarker ? ` ${classes.pinMarker}` : ""}`,
|
|
450
475
|
style: {
|
|
451
476
|
background: pin.color,
|
|
452
477
|
left: pin.x,
|
|
@@ -456,7 +481,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
456
481
|
},
|
|
457
482
|
i
|
|
458
483
|
)),
|
|
459
|
-
showForm && /* @__PURE__ */ jsxs("div", { className:
|
|
484
|
+
showForm && /* @__PURE__ */ jsxs("div", { className: `feedtack-form${classes.form ? ` ${classes.form}` : ""}`, style: { position: "fixed", ...formPos }, children: [
|
|
460
485
|
/* @__PURE__ */ jsx(
|
|
461
486
|
"textarea",
|
|
462
487
|
{
|
|
@@ -477,7 +502,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
477
502
|
{
|
|
478
503
|
className: sentiment === "satisfied" ? "selected" : "",
|
|
479
504
|
onClick: () => setSentiment(sentiment === "satisfied" ? null : "satisfied"),
|
|
480
|
-
children: "\u{1F60A} Satisfied"
|
|
505
|
+
children: sentimentLabels.satisfied ?? "\u{1F60A} Satisfied"
|
|
481
506
|
}
|
|
482
507
|
),
|
|
483
508
|
/* @__PURE__ */ jsx(
|
|
@@ -485,7 +510,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
485
510
|
{
|
|
486
511
|
className: sentiment === "dissatisfied" ? "selected" : "",
|
|
487
512
|
onClick: () => setSentiment(sentiment === "dissatisfied" ? null : "dissatisfied"),
|
|
488
|
-
children: "\u{1F61E} Dissatisfied"
|
|
513
|
+
children: sentimentLabels.dissatisfied ?? "\u{1F61E} Dissatisfied"
|
|
489
514
|
}
|
|
490
515
|
)
|
|
491
516
|
] }),
|
|
@@ -500,7 +525,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
500
525
|
return /* @__PURE__ */ jsx(
|
|
501
526
|
"div",
|
|
502
527
|
{
|
|
503
|
-
className:
|
|
528
|
+
className: `feedtack-pin-marker${classes.pinMarker ? ` ${classes.pinMarker}` : ""}`,
|
|
504
529
|
style: {
|
|
505
530
|
background: firstItemPin.color,
|
|
506
531
|
left: firstItemPin.x,
|
|
@@ -519,7 +544,7 @@ function FeedtackProvider({ children, adapter, currentUser, hotkey = "p", adminO
|
|
|
519
544
|
if (!item) return null;
|
|
520
545
|
const pin = item.payload.pins[0];
|
|
521
546
|
const pos = getAnchoredPosition(pin.x, pin.y);
|
|
522
|
-
return /* @__PURE__ */ jsxs("div", { className:
|
|
547
|
+
return /* @__PURE__ */ jsxs("div", { className: `feedtack-thread${classes.thread ? ` ${classes.thread}` : ""}`, style: { position: "fixed", ...pos }, children: [
|
|
523
548
|
/* @__PURE__ */ jsx("strong", { style: { fontSize: 13 }, children: item.payload.submittedBy.name }),
|
|
524
549
|
/* @__PURE__ */ jsx("p", { style: { fontSize: 13 }, children: item.payload.comment }),
|
|
525
550
|
item.replies.map((r) => /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid #f3f4f6", paddingTop: 8 }, children: [
|
|
@@ -122,4 +122,25 @@ interface FeedtackAdapter {
|
|
|
122
122
|
loadFeedback(filter?: FeedtackFilter): Promise<FeedbackItem[]>;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
interface FeedtackTheme {
|
|
126
|
+
/** Accent color — pin button active state, focus rings, selected states */
|
|
127
|
+
primary?: string;
|
|
128
|
+
/** Panel and picker background */
|
|
129
|
+
background?: string;
|
|
130
|
+
/** Input and card surface background */
|
|
131
|
+
surface?: string;
|
|
132
|
+
/** Primary text color */
|
|
133
|
+
text?: string;
|
|
134
|
+
/** Secondary/placeholder text color */
|
|
135
|
+
textMuted?: string;
|
|
136
|
+
/** Panel and input border color */
|
|
137
|
+
border?: string;
|
|
138
|
+
/** Border radius applied to panels and inputs */
|
|
139
|
+
radius?: string;
|
|
140
|
+
/** Notification badge color */
|
|
141
|
+
badge?: string;
|
|
142
|
+
}
|
|
143
|
+
/** Maps FeedtackTheme fields to CSS custom properties on #feedtack-root */
|
|
144
|
+
declare function themeToCSS(theme: FeedtackTheme): Record<string, string>;
|
|
145
|
+
|
|
146
|
+
export { type FeedtackAdapter as F, SCHEMA_VERSION as S, type FeedtackPayload as a, type FeedtackReply as b, type FeedtackResolution as c, type FeedtackFilter as d, type FeedbackItem as e, type FeedtackPinTarget as f, type FeedtackDeviceMeta as g, type FeedtackPageMeta as h, type FeedtackViewportMeta as i, type FeedtackArchive as j, type FeedtackBoundingRect as k, type FeedtackPin as l, type FeedtackSentiment as m, type FeedtackTheme as n, type FeedtackUser as o, themeToCSS as t };
|