@openfeed-ink/widget 0.1.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.
Files changed (43) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +141 -0
  3. package/dist/npm/AnnouncementBanner-BPo8Jmax.js +75 -0
  4. package/dist/npm/App.d.ts +5 -0
  5. package/dist/npm/ChangelogTab-DBQ5Ip6K.js +18 -0
  6. package/dist/npm/DrawerType-D9YHimv7.js +1184 -0
  7. package/dist/npm/FeatureDialog-BU1c2n3F.js +31 -0
  8. package/dist/npm/FeedbackTab-V7VCrze1.js +71 -0
  9. package/dist/npm/Main.d.ts +5 -0
  10. package/dist/npm/PopoverType-DlyRog2q.js +1863 -0
  11. package/dist/npm/RoadmapTab-DOYJBpgd.js +18 -0
  12. package/dist/npm/WidgetContent-Bs4eY5OF.js +507 -0
  13. package/dist/npm/button-Q2Dh1yK6.js +3086 -0
  14. package/dist/npm/components/AnnouncementBanner.d.ts +4 -0
  15. package/dist/npm/components/ChangelogTab.d.ts +6 -0
  16. package/dist/npm/components/FeatureDialog.d.ts +5 -0
  17. package/dist/npm/components/FeedbackTab.d.ts +8 -0
  18. package/dist/npm/components/NewFeedback.d.ts +9 -0
  19. package/dist/npm/components/RoadmapTab.d.ts +6 -0
  20. package/dist/npm/components/WidgetContent.d.ts +8 -0
  21. package/dist/npm/components/theme-provider.d.ts +8 -0
  22. package/dist/npm/components/triggerType/DrawerType.d.ts +11 -0
  23. package/dist/npm/components/triggerType/PopoverType.d.ts +11 -0
  24. package/dist/npm/components/ui/button.d.ts +10 -0
  25. package/dist/npm/components/ui/dialog.d.ts +11 -0
  26. package/dist/npm/components/ui/drawer.d.ts +10 -0
  27. package/dist/npm/components/ui/popover.d.ts +7 -0
  28. package/dist/npm/components/ui/tabs.d.ts +11 -0
  29. package/dist/npm/context/outsideEvent.d.ts +17 -0
  30. package/dist/npm/context/shadow-root.d.ts +5 -0
  31. package/dist/npm/dialog-5J_RZfbt.js +107 -0
  32. package/dist/npm/hooks/use-local-storage.d.ts +1 -0
  33. package/dist/npm/index-BaBFRQOq.js +1043 -0
  34. package/dist/npm/index-BkmaVINv.js +334 -0
  35. package/dist/npm/index-MTTUickr.js +237 -0
  36. package/dist/npm/index.d.ts +2 -0
  37. package/dist/npm/index.js +6 -0
  38. package/dist/npm/lib/utils.d.ts +2 -0
  39. package/dist/npm/mount.d.ts +7 -0
  40. package/dist/npm/react/OpenFeed.d.ts +7 -0
  41. package/dist/npm/types/index.d.ts +31 -0
  42. package/dist/npm/x-BkA0RvhX.js +9 -0
  43. package/package.json +95 -0
@@ -0,0 +1,237 @@
1
+ "use client";
2
+ import * as i from "react";
3
+ import { P as p, e as g, b as V, d as R, f as _, c as q, g as K, h as U, R as Y, i as Z, F as z, D as J, j as Q } from "./index-BaBFRQOq.js";
4
+ import { u as h, a as X } from "./button-Q2Dh1yK6.js";
5
+ import { jsx as s, jsxs as N, Fragment as O } from "react/jsx-runtime";
6
+ var v = "Dialog", [I] = q(v), [ee, u] = I(v), x = (e) => {
7
+ const {
8
+ __scopeDialog: o,
9
+ children: r,
10
+ open: a,
11
+ defaultOpen: n,
12
+ onOpenChange: t,
13
+ modal: l = !0
14
+ } = e, c = i.useRef(null), f = i.useRef(null), [m, C] = V({
15
+ prop: a,
16
+ defaultProp: n ?? !1,
17
+ onChange: t,
18
+ caller: v
19
+ });
20
+ return /* @__PURE__ */ s(
21
+ ee,
22
+ {
23
+ scope: o,
24
+ triggerRef: c,
25
+ contentRef: f,
26
+ contentId: R(),
27
+ titleId: R(),
28
+ descriptionId: R(),
29
+ open: m,
30
+ onOpenChange: C,
31
+ onOpenToggle: i.useCallback(() => C((H) => !H), [C]),
32
+ modal: l,
33
+ children: r
34
+ }
35
+ );
36
+ };
37
+ x.displayName = v;
38
+ var A = "DialogTrigger", T = i.forwardRef(
39
+ (e, o) => {
40
+ const { __scopeDialog: r, ...a } = e, n = u(A, r), t = h(o, n.triggerRef);
41
+ return /* @__PURE__ */ s(
42
+ p.button,
43
+ {
44
+ type: "button",
45
+ "aria-haspopup": "dialog",
46
+ "aria-expanded": n.open,
47
+ "aria-controls": n.contentId,
48
+ "data-state": y(n.open),
49
+ ...a,
50
+ ref: t,
51
+ onClick: g(e.onClick, n.onOpenToggle)
52
+ }
53
+ );
54
+ }
55
+ );
56
+ T.displayName = A;
57
+ var E = "DialogPortal", [te, b] = I(E, {
58
+ forceMount: void 0
59
+ }), M = (e) => {
60
+ const { __scopeDialog: o, forceMount: r, children: a, container: n } = e, t = u(E, o);
61
+ return /* @__PURE__ */ s(te, { scope: o, forceMount: r, children: i.Children.map(a, (l) => /* @__PURE__ */ s(_, { present: r || t.open, children: /* @__PURE__ */ s(K, { asChild: !0, container: n, children: l }) })) });
62
+ };
63
+ M.displayName = E;
64
+ var D = "DialogOverlay", w = i.forwardRef(
65
+ (e, o) => {
66
+ const r = b(D, e.__scopeDialog), { forceMount: a = r.forceMount, ...n } = e, t = u(D, e.__scopeDialog);
67
+ return t.modal ? /* @__PURE__ */ s(_, { present: a || t.open, children: /* @__PURE__ */ s(ne, { ...n, ref: o }) }) : null;
68
+ }
69
+ );
70
+ w.displayName = D;
71
+ var oe = X("DialogOverlay.RemoveScroll"), ne = i.forwardRef(
72
+ (e, o) => {
73
+ const { __scopeDialog: r, ...a } = e, n = u(D, r);
74
+ return (
75
+ // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`
76
+ // ie. when `Overlay` and `Content` are siblings
77
+ /* @__PURE__ */ s(Y, { as: oe, allowPinchZoom: !0, shards: [n.contentRef], children: /* @__PURE__ */ s(
78
+ p.div,
79
+ {
80
+ "data-state": y(n.open),
81
+ ...a,
82
+ ref: o,
83
+ style: { pointerEvents: "auto", ...a.style }
84
+ }
85
+ ) })
86
+ );
87
+ }
88
+ ), d = "DialogContent", F = i.forwardRef(
89
+ (e, o) => {
90
+ const r = b(d, e.__scopeDialog), { forceMount: a = r.forceMount, ...n } = e, t = u(d, e.__scopeDialog);
91
+ return /* @__PURE__ */ s(_, { present: a || t.open, children: t.modal ? /* @__PURE__ */ s(re, { ...n, ref: o }) : /* @__PURE__ */ s(ae, { ...n, ref: o }) });
92
+ }
93
+ );
94
+ F.displayName = d;
95
+ var re = i.forwardRef(
96
+ (e, o) => {
97
+ const r = u(d, e.__scopeDialog), a = i.useRef(null), n = h(o, r.contentRef, a);
98
+ return i.useEffect(() => {
99
+ const t = a.current;
100
+ if (t) return U(t);
101
+ }, []), /* @__PURE__ */ s(
102
+ S,
103
+ {
104
+ ...e,
105
+ ref: n,
106
+ trapFocus: r.open,
107
+ disableOutsidePointerEvents: !0,
108
+ onCloseAutoFocus: g(e.onCloseAutoFocus, (t) => {
109
+ t.preventDefault(), r.triggerRef.current?.focus();
110
+ }),
111
+ onPointerDownOutside: g(e.onPointerDownOutside, (t) => {
112
+ const l = t.detail.originalEvent, c = l.button === 0 && l.ctrlKey === !0;
113
+ (l.button === 2 || c) && t.preventDefault();
114
+ }),
115
+ onFocusOutside: g(
116
+ e.onFocusOutside,
117
+ (t) => t.preventDefault()
118
+ )
119
+ }
120
+ );
121
+ }
122
+ ), ae = i.forwardRef(
123
+ (e, o) => {
124
+ const r = u(d, e.__scopeDialog), a = i.useRef(!1), n = i.useRef(!1);
125
+ return /* @__PURE__ */ s(
126
+ S,
127
+ {
128
+ ...e,
129
+ ref: o,
130
+ trapFocus: !1,
131
+ disableOutsidePointerEvents: !1,
132
+ onCloseAutoFocus: (t) => {
133
+ e.onCloseAutoFocus?.(t), t.defaultPrevented || (a.current || r.triggerRef.current?.focus(), t.preventDefault()), a.current = !1, n.current = !1;
134
+ },
135
+ onInteractOutside: (t) => {
136
+ e.onInteractOutside?.(t), t.defaultPrevented || (a.current = !0, t.detail.originalEvent.type === "pointerdown" && (n.current = !0));
137
+ const l = t.target;
138
+ r.triggerRef.current?.contains(l) && t.preventDefault(), t.detail.originalEvent.type === "focusin" && n.current && t.preventDefault();
139
+ }
140
+ }
141
+ );
142
+ }
143
+ ), S = i.forwardRef(
144
+ (e, o) => {
145
+ const { __scopeDialog: r, trapFocus: a, onOpenAutoFocus: n, onCloseAutoFocus: t, ...l } = e, c = u(d, r), f = i.useRef(null), m = h(o, f);
146
+ return Z(), /* @__PURE__ */ N(O, { children: [
147
+ /* @__PURE__ */ s(
148
+ z,
149
+ {
150
+ asChild: !0,
151
+ loop: !0,
152
+ trapped: a,
153
+ onMountAutoFocus: n,
154
+ onUnmountAutoFocus: t,
155
+ children: /* @__PURE__ */ s(
156
+ J,
157
+ {
158
+ role: "dialog",
159
+ id: c.contentId,
160
+ "aria-describedby": c.descriptionId,
161
+ "aria-labelledby": c.titleId,
162
+ "data-state": y(c.open),
163
+ ...l,
164
+ ref: m,
165
+ onDismiss: () => c.onOpenChange(!1)
166
+ }
167
+ )
168
+ }
169
+ ),
170
+ /* @__PURE__ */ N(O, { children: [
171
+ /* @__PURE__ */ s(se, { titleId: c.titleId }),
172
+ /* @__PURE__ */ s(ce, { contentRef: f, descriptionId: c.descriptionId })
173
+ ] })
174
+ ] });
175
+ }
176
+ ), P = "DialogTitle", W = i.forwardRef(
177
+ (e, o) => {
178
+ const { __scopeDialog: r, ...a } = e, n = u(P, r);
179
+ return /* @__PURE__ */ s(p.h2, { id: n.titleId, ...a, ref: o });
180
+ }
181
+ );
182
+ W.displayName = P;
183
+ var k = "DialogDescription", G = i.forwardRef(
184
+ (e, o) => {
185
+ const { __scopeDialog: r, ...a } = e, n = u(k, r);
186
+ return /* @__PURE__ */ s(p.p, { id: n.descriptionId, ...a, ref: o });
187
+ }
188
+ );
189
+ G.displayName = k;
190
+ var L = "DialogClose", $ = i.forwardRef(
191
+ (e, o) => {
192
+ const { __scopeDialog: r, ...a } = e, n = u(L, r);
193
+ return /* @__PURE__ */ s(
194
+ p.button,
195
+ {
196
+ type: "button",
197
+ ...a,
198
+ ref: o,
199
+ onClick: g(e.onClick, () => n.onOpenChange(!1))
200
+ }
201
+ );
202
+ }
203
+ );
204
+ $.displayName = L;
205
+ function y(e) {
206
+ return e ? "open" : "closed";
207
+ }
208
+ var j = "DialogTitleWarning", [fe, B] = Q(j, {
209
+ contentName: d,
210
+ titleName: P,
211
+ docsSlug: "dialog"
212
+ }), se = ({ titleId: e }) => {
213
+ const o = B(j), r = `\`${o.contentName}\` requires a \`${o.titleName}\` for the component to be accessible for screen reader users.
214
+
215
+ If you want to hide the \`${o.titleName}\`, you can wrap it with our VisuallyHidden component.
216
+
217
+ For more information, see https://radix-ui.com/primitives/docs/components/${o.docsSlug}`;
218
+ return i.useEffect(() => {
219
+ e && (document.getElementById(e) || console.error(r));
220
+ }, [r, e]), null;
221
+ }, ie = "DialogDescriptionWarning", ce = ({ contentRef: e, descriptionId: o }) => {
222
+ const a = `Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${B(ie).contentName}}.`;
223
+ return i.useEffect(() => {
224
+ const n = e.current?.getAttribute("aria-describedby");
225
+ o && n && (document.getElementById(o) || console.warn(a));
226
+ }, [a, e, o]), null;
227
+ }, ge = x, pe = T, De = M, ve = w, me = F, Ce = W, Re = G, _e = $;
228
+ export {
229
+ me as C,
230
+ Re as D,
231
+ ve as O,
232
+ De as P,
233
+ ge as R,
234
+ pe as T,
235
+ Ce as a,
236
+ _e as b
237
+ };
@@ -0,0 +1,2 @@
1
+ export { mount } from './mount';
2
+ export { OpenFeed } from './react/OpenFeed';
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ import { O as n, m as o } from "./index-BkmaVINv.js";
3
+ export {
4
+ n as OpenFeed,
5
+ o as mount
6
+ };
@@ -0,0 +1,2 @@
1
+ import { ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,7 @@
1
+ interface RawConfig {
2
+ projectId?: string;
3
+ apiUrl?: string;
4
+ prod?: string;
5
+ }
6
+ export declare function mount(rawConfig: RawConfig): void;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ projectId: string;
3
+ apiUrl?: string;
4
+ prod?: string;
5
+ };
6
+ export declare const OpenFeed: ({ projectId, apiUrl, prod }: Props) => null;
7
+ export {};
@@ -0,0 +1,31 @@
1
+ export interface WidgetConfig {
2
+ projectId: string;
3
+ apiUrl: string;
4
+ prod: boolean;
5
+ }
6
+ export type AnnouncementConfig = {
7
+ position: 'top' | 'bottom';
8
+ text: string;
9
+ link?: string;
10
+ dismiss: boolean;
11
+ bgcolor: string;
12
+ textcolor: string;
13
+ actionBtn: string;
14
+ };
15
+ export type Config = {
16
+ theme: "dark" | "light" | "system";
17
+ widgetName: string;
18
+ info: string | null;
19
+ triggerBtn: {
20
+ position: "float-bottom-right" | "float-bottom-left" | "float-up-right" | "float-up-left" | "drawer-left" | "drawer-right";
21
+ color: string;
22
+ textColor: string;
23
+ size: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg";
24
+ text: string | null;
25
+ icon: string | null;
26
+ };
27
+ showFeedback: boolean;
28
+ showChangeLog: boolean;
29
+ showRoadmap: boolean;
30
+ announcement?: AnnouncementConfig;
31
+ };
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { c as e } from "./index-BkmaVINv.js";
3
+ const c = [
4
+ ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
5
+ ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
6
+ ], t = e("x", c);
7
+ export {
8
+ t as X
9
+ };
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@openfeed-ink/widget",
3
+ "version": "0.1.3",
4
+ "description": "Embeddable feedback, roadmap and changelog widget for OpenFeed — the open source alternative to Canny and Frill. One script tag. Full control from your dashboard.",
5
+ "author": {
6
+ "name": "Ali Amer",
7
+ "email": "aliamer19ali@gmail.com",
8
+ "url": "https://openfeed.ink"
9
+ },
10
+ "license": "AGPL-3.0-only",
11
+ "homepage": "https://openfeed.ink",
12
+ "main": "./dist/npm/index.js",
13
+ "module": "./dist/npm/index.js",
14
+ "types": "./dist/npm/index.d.ts",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/OpenFeed-ink/openfeed-widget"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/OpenFeed-ink/openfeed-widget/issues"
21
+ },
22
+ "keywords": [
23
+ "feedback",
24
+ "feedback-widget",
25
+ "changelog",
26
+ "roadmap",
27
+ "feature-requests",
28
+ "upvoting",
29
+ "canny-alternative",
30
+ "frill-alternative",
31
+ "open-source",
32
+ "self-hosted",
33
+ "user-feedback",
34
+ "product-feedback",
35
+ "saas",
36
+ "widget",
37
+ "embeddable",
38
+ "react",
39
+ "typescript"
40
+ ],
41
+ "exports": {
42
+ ".": {
43
+ "import": "./dist/npm/index.js",
44
+ "types": "./dist/npm/index.d.ts"
45
+ }
46
+ },
47
+ "files": [
48
+ "dist/npm",
49
+ "README.md",
50
+ "LICENSE"
51
+ ],
52
+ "private": false,
53
+ "type": "module",
54
+ "scripts": {
55
+ "dev": "vite",
56
+ "build": "vite build --mode cdn && vite build --mode npm",
57
+ "lint": "eslint .",
58
+ "format": "prettier --write \"**/*.{ts,tsx}\"",
59
+ "typecheck": "tsc --noEmit",
60
+ "preview": "vite preview"
61
+ },
62
+ "dependencies": {
63
+ "@fontsource-variable/roboto": "^5.2.10",
64
+ "@tailwindcss/vite": "^4.1.17",
65
+ "class-variance-authority": "^0.7.1",
66
+ "clsx": "^2.1.1",
67
+ "lucide-react": "^0.577.0",
68
+ "radix-ui": "^1.4.3",
69
+ "react": "^19.2.0",
70
+ "react-dom": "^19.2.0",
71
+ "shadcn": "^4.0.0",
72
+ "tailwind-merge": "^3.5.0",
73
+ "tailwindcss": "^4.1.17",
74
+ "tw-animate-css": "^1.4.0",
75
+ "vaul": "^1.1.2"
76
+ },
77
+ "devDependencies": {
78
+ "@eslint/js": "^9.39.1",
79
+ "@types/node": "^24.10.1",
80
+ "@types/react": "^19.2.5",
81
+ "@types/react-dom": "^19.2.3",
82
+ "@vitejs/plugin-react": "^5.1.1",
83
+ "eslint": "^9.39.1",
84
+ "eslint-plugin-react-hooks": "^7.0.1",
85
+ "eslint-plugin-react-refresh": "^0.4.24",
86
+ "globals": "^16.5.0",
87
+ "prettier": "^3.8.1",
88
+ "prettier-plugin-tailwindcss": "^0.7.2",
89
+ "rollup-plugin-visualizer": "^7.0.1",
90
+ "typescript": "~5.9.3",
91
+ "typescript-eslint": "^8.46.4",
92
+ "vite": "^7.2.4",
93
+ "vite-plugin-dts": "^4.5.4"
94
+ }
95
+ }