@fastbackr/react 0.0.0-stage → 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.
- package/LICENSE +46 -0
- package/README.md +216 -2
- package/dist/app-Cw3fHqqr.js +1615 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +132 -0
- package/package.json +66 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
import { FastbackrOptions, GetToken, GetToken as GetToken$1 } from "@fastbackr/core/boot";
|
|
3
|
+
import { ReactNode, Ref } from "react";
|
|
4
|
+
import { CreateTokenResponse, ErrorCode, ErrorEnvelope, GuestIdentity, Reviewer } from "@fastbackr/core/contract";
|
|
5
|
+
//#region src/fastbackr.d.ts
|
|
6
|
+
type FastbackrHandle = Readonly<{
|
|
7
|
+
show(): void;
|
|
8
|
+
hide(): void;
|
|
9
|
+
}>;
|
|
10
|
+
type FastbackrProps = FastbackrOptions & Readonly<{
|
|
11
|
+
ref?: Ref<FastbackrHandle>;
|
|
12
|
+
}>;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/provider.d.ts
|
|
15
|
+
type FastbackrProviderProps = Omit<FastbackrProps, "getToken" | "ref"> & Readonly<{
|
|
16
|
+
tokenUrl?: string;
|
|
17
|
+
getToken?: GetToken$1;
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function FastbackrProvider({ tokenUrl, getToken, children, ...options }: FastbackrProviderProps): import("react").JSX.Element;
|
|
21
|
+
export declare function useFastbackr(): FastbackrHandle;
|
|
22
|
+
//#endregion
|
|
23
|
+
export type { CreateTokenResponse, ErrorCode, ErrorEnvelope, FastbackrHandle, FastbackrProviderProps, GetToken, GuestIdentity, Reviewer };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { DEFAULT_ENDPOINT, Fab, isHidden, normalizeEndpoint, rememberHidden, rememberVisible, shouldRevealOnLoad, tokenRoute, watchCsp, watchRevealGesture } from "@fastbackr/core/boot";
|
|
3
|
+
import { Component, Suspense, createContext, lazy, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/fastbackr.tsx
|
|
6
|
+
const App = lazy(() => import("./app-Cw3fHqqr.js"));
|
|
7
|
+
const instanceKey = Symbol.for("fastbackr.instance");
|
|
8
|
+
function Fastbackr({ ref, ...props }) {
|
|
9
|
+
if (typeof props.getToken !== "function") throw new TypeError("<FastbackrProvider>'s getToken must be a function that calls your own token route.");
|
|
10
|
+
const latest = useRef(props);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
latest.current = props;
|
|
13
|
+
});
|
|
14
|
+
const [options] = useState(() => ({
|
|
15
|
+
...props,
|
|
16
|
+
endpoint: normalizeEndpoint(props.endpoint ?? DEFAULT_ENDPOINT),
|
|
17
|
+
getToken: (guest) => latest.current.getToken(guest),
|
|
18
|
+
signIn: props.signIn && (() => latest.current.signIn?.())
|
|
19
|
+
}));
|
|
20
|
+
const [open, setOpen] = useState(false);
|
|
21
|
+
const [commentRequest, setCommentRequest] = useState(0);
|
|
22
|
+
const [flashRequest, setFlashRequest] = useState(0);
|
|
23
|
+
const fab = useRef(null);
|
|
24
|
+
const [drafts] = useState(() => /* @__PURE__ */ new Map());
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const state = globalThis;
|
|
27
|
+
if (state[instanceKey]) return;
|
|
28
|
+
const owner = {};
|
|
29
|
+
state[instanceKey] = owner;
|
|
30
|
+
const abort = new AbortController();
|
|
31
|
+
const button = new Fab(() => {
|
|
32
|
+
setOpen(true);
|
|
33
|
+
setCommentRequest((count) => count + 1);
|
|
34
|
+
});
|
|
35
|
+
fab.current = button;
|
|
36
|
+
watchRevealGesture(() => {
|
|
37
|
+
rememberHidden(false);
|
|
38
|
+
setOpen(true);
|
|
39
|
+
}, abort.signal);
|
|
40
|
+
watchCsp(new URL(options.endpoint).origin, abort.signal);
|
|
41
|
+
if (shouldRevealOnLoad()) setOpen(true);
|
|
42
|
+
else if (!isHidden()) button.show();
|
|
43
|
+
return () => {
|
|
44
|
+
abort.abort();
|
|
45
|
+
button.hide();
|
|
46
|
+
fab.current = null;
|
|
47
|
+
setOpen(false);
|
|
48
|
+
if (state[instanceKey] === owner) delete state[instanceKey];
|
|
49
|
+
};
|
|
50
|
+
}, [options]);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (open) rememberVisible(true);
|
|
53
|
+
}, [open]);
|
|
54
|
+
const hideFab = useCallback(() => fab.current?.hide(), []);
|
|
55
|
+
const showFab = useCallback(() => {
|
|
56
|
+
if (!isHidden()) fab.current?.show();
|
|
57
|
+
}, []);
|
|
58
|
+
const minimize = () => {
|
|
59
|
+
setOpen(false);
|
|
60
|
+
rememberVisible(false);
|
|
61
|
+
showFab();
|
|
62
|
+
};
|
|
63
|
+
const close = () => {
|
|
64
|
+
setOpen(false);
|
|
65
|
+
fab.current?.hide();
|
|
66
|
+
rememberVisible(false);
|
|
67
|
+
rememberHidden(true);
|
|
68
|
+
};
|
|
69
|
+
useImperativeHandle(ref, () => ({
|
|
70
|
+
show() {
|
|
71
|
+
rememberHidden(false);
|
|
72
|
+
if (open) setFlashRequest((count) => count + 1);
|
|
73
|
+
else {
|
|
74
|
+
fab.current?.show();
|
|
75
|
+
fab.current?.flash();
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
hide: close
|
|
79
|
+
}));
|
|
80
|
+
if (!open) return null;
|
|
81
|
+
return /* @__PURE__ */ jsx(LoadFailure, { children: /* @__PURE__ */ jsx(Suspense, {
|
|
82
|
+
fallback: null,
|
|
83
|
+
children: /* @__PURE__ */ jsx(App, {
|
|
84
|
+
options,
|
|
85
|
+
drafts,
|
|
86
|
+
commentRequest,
|
|
87
|
+
flashRequest,
|
|
88
|
+
hideFab,
|
|
89
|
+
showFab,
|
|
90
|
+
minimize,
|
|
91
|
+
close
|
|
92
|
+
})
|
|
93
|
+
}) });
|
|
94
|
+
}
|
|
95
|
+
var LoadFailure = class extends Component {
|
|
96
|
+
state = { failed: false };
|
|
97
|
+
static getDerivedStateFromError() {
|
|
98
|
+
return { failed: true };
|
|
99
|
+
}
|
|
100
|
+
componentDidCatch(error) {
|
|
101
|
+
console.error("Fastbackr could not load:", error instanceof Error ? error.message : "Unknown error");
|
|
102
|
+
}
|
|
103
|
+
render() {
|
|
104
|
+
return this.state.failed ? null : this.props.children;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/provider.tsx
|
|
109
|
+
const FastbackrContext = createContext(null);
|
|
110
|
+
function FastbackrProvider({ tokenUrl, getToken, children, ...options }) {
|
|
111
|
+
const sdk = useRef(null);
|
|
112
|
+
const [handle] = useState(() => ({
|
|
113
|
+
show: () => sdk.current?.show(),
|
|
114
|
+
hide: () => sdk.current?.hide()
|
|
115
|
+
}));
|
|
116
|
+
const fromRoute = useMemo(() => tokenRoute(tokenUrl), [tokenUrl]);
|
|
117
|
+
return /* @__PURE__ */ jsxs(FastbackrContext, {
|
|
118
|
+
value: handle,
|
|
119
|
+
children: [children, /* @__PURE__ */ jsx(Fastbackr, {
|
|
120
|
+
ref: sdk,
|
|
121
|
+
getToken: getToken ?? fromRoute,
|
|
122
|
+
...options
|
|
123
|
+
})]
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
function useFastbackr() {
|
|
127
|
+
const handle = useContext(FastbackrContext);
|
|
128
|
+
if (!handle) throw new Error("useFastbackr() must be used inside <FastbackrProvider>.");
|
|
129
|
+
return handle;
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
export { FastbackrProvider, useFastbackr };
|
package/package.json
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastbackr/react",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Comment on any element of a web page. The React SDK for Fastbackr.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"homepage": "https://fastbackr.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/HuggerHustle/fastbackr.git",
|
|
10
|
+
"directory": "packages/react"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./package.json": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@base-ui/react": "^1.8.0",
|
|
33
|
+
"@fastbackr/core": "0.0.3",
|
|
34
|
+
"@remixicon/react": "^4.9.0",
|
|
35
|
+
"class-variance-authority": "^0.7.1",
|
|
36
|
+
"cn": "^0.4.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^19",
|
|
40
|
+
"react-dom": "^19"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@biomejs/biome": "2.4.2",
|
|
44
|
+
"@fastbackr/config-biome": "0.0.3",
|
|
45
|
+
"@fastbackr/config-typescript": "0.0.3",
|
|
46
|
+
"@fastbackr/ui": "0.0.3",
|
|
47
|
+
"@tailwindcss/postcss": "^4",
|
|
48
|
+
"@types/node": "^24.10.1",
|
|
49
|
+
"@types/react": "^19",
|
|
50
|
+
"@types/react-dom": "^19",
|
|
51
|
+
"postcss": "^8",
|
|
52
|
+
"react": "19.2.8",
|
|
53
|
+
"react-dom": "19.2.8",
|
|
54
|
+
"shadcn": "^4.21.1",
|
|
55
|
+
"tailwind-animations": "^1.0.2",
|
|
56
|
+
"tailwindcss": "^4",
|
|
57
|
+
"tsdown": "^0.23.0",
|
|
58
|
+
"tw-animate-css": "^1.4.0",
|
|
59
|
+
"typescript": "~5.9.3"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsdown",
|
|
63
|
+
"dev": "tsdown --watch",
|
|
64
|
+
"typecheck": "tsc --noEmit",
|
|
65
|
+
"test": "node --test --experimental-strip-types \"src/**/*.test.ts\"",
|
|
66
|
+
"lint": "biome check",
|
|
67
|
+
"format": "biome format --write"
|
|
68
|
+
}
|
|
6
69
|
}
|