@fewchurs/react 1.0.1 → 1.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/README.md +5 -2
- package/dist/core.d.mts +8 -3
- package/dist/core.d.ts +8 -3
- package/dist/core.js +8 -5
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +8 -5
- package/dist/core.mjs.map +1 -1
- package/dist/index.d.mts +19 -5
- package/dist/index.d.ts +19 -5
- package/dist/index.js +59 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -7
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +107 -0
- package/package.json +1 -6
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { ReactNode, CSSProperties } from 'react';
|
|
|
2
2
|
|
|
3
3
|
type FewchursError = {
|
|
4
4
|
code: "invalid_key";
|
|
5
|
-
status: 401;
|
|
5
|
+
status: 401 | 403;
|
|
6
6
|
message: string;
|
|
7
7
|
} | {
|
|
8
8
|
code: "validation_failed";
|
|
@@ -110,6 +110,11 @@ interface FewchursClientOptions {
|
|
|
110
110
|
deviceId?: string | null | (() => string | null);
|
|
111
111
|
/** Sent as `Accept-Language`, so server-side copy and emails match the visitor. */
|
|
112
112
|
language?: string;
|
|
113
|
+
/**
|
|
114
|
+
* The domain the API key is checked against, for calls made from a server. A browser reports
|
|
115
|
+
* its own domain through `Origin`, which always wins, so leave this out in a SPA.
|
|
116
|
+
*/
|
|
117
|
+
appId?: string;
|
|
113
118
|
fetch?: FetchLike;
|
|
114
119
|
retries?: number;
|
|
115
120
|
retryDelayMs?: number;
|
|
@@ -308,9 +313,9 @@ declare function useBoard(): BoardContextValue;
|
|
|
308
313
|
|
|
309
314
|
declare function Branding(): React.JSX.Element | null;
|
|
310
315
|
|
|
311
|
-
declare const SDK_VERSION = "1.0
|
|
316
|
+
declare const SDK_VERSION = "1.2.0";
|
|
312
317
|
|
|
313
|
-
declare const SDK_HEADER = "react/1.0
|
|
318
|
+
declare const SDK_HEADER = "react/1.2.0";
|
|
314
319
|
declare const DEFAULT_BASE_URL = "https://www.fewchurs.com/api/v1";
|
|
315
320
|
declare const DEFAULT_PAGE_SIZE = 20;
|
|
316
321
|
/** Mirrors the server's zod schemas, so the UI can reject input before a round trip. */
|
|
@@ -381,8 +386,17 @@ interface FewchursBoardDialogProps extends FewchursBoardProps {
|
|
|
381
386
|
open: boolean;
|
|
382
387
|
onClose: () => void;
|
|
383
388
|
ariaLabel?: string;
|
|
389
|
+
variant?: "dialog" | "sheet";
|
|
384
390
|
}
|
|
385
|
-
declare function FewchursBoardDialog({ open, onClose, ariaLabel, ...boardProps }: FewchursBoardDialogProps): React.JSX.Element | null;
|
|
391
|
+
declare function FewchursBoardDialog({ open, onClose, ariaLabel, variant, ...boardProps }: FewchursBoardDialogProps): React.JSX.Element | null;
|
|
392
|
+
|
|
393
|
+
interface FewchursButtonProps extends Omit<FewchursBoardProps, "children" | "className" | "style"> {
|
|
394
|
+
children?: ReactNode;
|
|
395
|
+
className?: string;
|
|
396
|
+
style?: CSSProperties;
|
|
397
|
+
ariaLabel?: string;
|
|
398
|
+
}
|
|
399
|
+
declare function FewchursButton({ children, className, style, ariaLabel, ...board }: FewchursButtonProps): React.JSX.Element;
|
|
386
400
|
|
|
387
401
|
declare function FeatureCard({ feature, defaultCommentsOpen, }: {
|
|
388
402
|
feature: Feature;
|
|
@@ -520,4 +534,4 @@ declare function validateFeatureInput(input: SubmitFeatureInput): FewchursError
|
|
|
520
534
|
declare function validateCommentInput(input: CreateCommentInput): FewchursError | null;
|
|
521
535
|
declare function validateEmail(email: string): FewchursError | null;
|
|
522
536
|
|
|
523
|
-
export { type BoardContextValue, type BoardLabels, BoardRoot, type BoardTab, BoardTabs, type BoardTheme, Branding, type Comment, CommentForm, CommentList, type CommentPage, type CommentsState, type CreateCommentInput, DEFAULT_BASE_URL, DEFAULT_LABELS, DEFAULT_PAGE_SIZE, COOKIE_NAME as DEVICE_ID_COOKIE, type EmailFieldMode, type EventHandler, type Feature, type FeatureActions, FeatureCard, FeatureList, type FeaturePage, type FeatureSort, type FeatureStatus, type FetchLike, FewchursBoard, FewchursBoardDialog, type FewchursBoardDialogProps, type FewchursBoardProps, type FewchursClient, type FewchursClientOptions, type FewchursConfig, type FewchursContextValue, type FewchursError, type FewchursEvent, type FewchursEventName, FewchursProvider, type FewchursProviderProps, FollowForm, LIMITS, type ListCommentsParams, type ListFeaturesParams, type ListQuery, type ListState, type LoadStatus, ROADMAP_STATUSES, type Result, SDK_HEADER, SDK_VERSION, StatusBadge, type Store, type StoreOptions, type StoreState, type SubmitFeatureInput, SubmitForm, SubmitTrigger, type UseCommentsOptions, type UseCommentsResult, type UseFeatureOptions, type UseFeatureResult, type UseFeaturesOptions, type UseFeaturesResult, type UseFewchursConfigResult, type UseFollowResult, type UseSubmitFeatureResult, type UseVoteResult, VoteButton, commentsStateOf, createDeviceId, createFewchursClient, createStore, errorFromResponse, featureKey, listKey, listStateOf, mergeLabels, networkError, normalizeComment, normalizeCommentPage, normalizeConfig, normalizeFeature, normalizeFeaturePage, normalizeStatus, normalizeVote, readDeviceId, resolveDeviceId, useBoard, useComments, useFeature, useFeatures, useFewchurs, useFewchursConfig, useFollow, useSubmitFeature, useVote, userMessage, validateCommentInput, validateEmail, validateFeatureInput, validationError };
|
|
537
|
+
export { type BoardContextValue, type BoardLabels, BoardRoot, type BoardTab, BoardTabs, type BoardTheme, Branding, type Comment, CommentForm, CommentList, type CommentPage, type CommentsState, type CreateCommentInput, DEFAULT_BASE_URL, DEFAULT_LABELS, DEFAULT_PAGE_SIZE, COOKIE_NAME as DEVICE_ID_COOKIE, type EmailFieldMode, type EventHandler, type Feature, type FeatureActions, FeatureCard, FeatureList, type FeaturePage, type FeatureSort, type FeatureStatus, type FetchLike, FewchursBoard, FewchursBoardDialog, type FewchursBoardDialogProps, type FewchursBoardProps, FewchursButton, type FewchursButtonProps, type FewchursClient, type FewchursClientOptions, type FewchursConfig, type FewchursContextValue, type FewchursError, type FewchursEvent, type FewchursEventName, FewchursProvider, type FewchursProviderProps, FollowForm, LIMITS, type ListCommentsParams, type ListFeaturesParams, type ListQuery, type ListState, type LoadStatus, ROADMAP_STATUSES, type Result, SDK_HEADER, SDK_VERSION, StatusBadge, type Store, type StoreOptions, type StoreState, type SubmitFeatureInput, SubmitForm, SubmitTrigger, type UseCommentsOptions, type UseCommentsResult, type UseFeatureOptions, type UseFeatureResult, type UseFeaturesOptions, type UseFeaturesResult, type UseFewchursConfigResult, type UseFollowResult, type UseSubmitFeatureResult, type UseVoteResult, VoteButton, commentsStateOf, createDeviceId, createFewchursClient, createStore, errorFromResponse, featureKey, listKey, listStateOf, mergeLabels, networkError, normalizeComment, normalizeCommentPage, normalizeConfig, normalizeFeature, normalizeFeaturePage, normalizeStatus, normalizeVote, readDeviceId, resolveDeviceId, useBoard, useComments, useFeature, useFeatures, useFewchurs, useFewchursConfig, useFollow, useSubmitFeature, useVote, userMessage, validateCommentInput, validateEmail, validateFeatureInput, validationError };
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(src_exports, {
|
|
|
34
34
|
FeatureList: () => FeatureList,
|
|
35
35
|
FewchursBoard: () => FewchursBoard,
|
|
36
36
|
FewchursBoardDialog: () => FewchursBoardDialog,
|
|
37
|
+
FewchursButton: () => FewchursButton,
|
|
37
38
|
FewchursProvider: () => FewchursProvider,
|
|
38
39
|
FollowForm: () => FollowForm,
|
|
39
40
|
LIMITS: () => LIMITS,
|
|
@@ -84,7 +85,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
84
85
|
var import_react = require("react");
|
|
85
86
|
|
|
86
87
|
// src/client/version.ts
|
|
87
|
-
var SDK_VERSION = "1.0
|
|
88
|
+
var SDK_VERSION = "1.2.0";
|
|
88
89
|
|
|
89
90
|
// src/client/constants.ts
|
|
90
91
|
var SDK_HEADER = `react/${SDK_VERSION}`;
|
|
@@ -127,6 +128,8 @@ function errorFromResponse(status, body) {
|
|
|
127
128
|
switch (code) {
|
|
128
129
|
case "invalid_key":
|
|
129
130
|
return { code: "invalid_key", status: 401, message };
|
|
131
|
+
case "wrong_app":
|
|
132
|
+
return { code: "invalid_key", status: 403, message };
|
|
130
133
|
// missing_device_id is a client mistake the caller fixes the same way a bad field is fixed,
|
|
131
134
|
// so it collapses into validation_failed rather than widening the public union.
|
|
132
135
|
case "missing_device_id":
|
|
@@ -276,6 +279,7 @@ function createFewchursClient(options = {}) {
|
|
|
276
279
|
const deviceId = getDeviceId();
|
|
277
280
|
if (deviceId) result["X-Device-Id"] = deviceId;
|
|
278
281
|
if (options.language) result["Accept-Language"] = options.language;
|
|
282
|
+
if (options.appId) result["X-Fewchurs-App-Id"] = options.appId;
|
|
279
283
|
return result;
|
|
280
284
|
}
|
|
281
285
|
function url(path, query) {
|
|
@@ -314,7 +318,7 @@ function createFewchursClient(options = {}) {
|
|
|
314
318
|
continue;
|
|
315
319
|
}
|
|
316
320
|
const failure = errorFromResponse(response.status, await readJson(response));
|
|
317
|
-
warnAboutKey(failure
|
|
321
|
+
warnAboutKey(failure);
|
|
318
322
|
return { ok: false, error: failure };
|
|
319
323
|
}
|
|
320
324
|
return { ok: false, error: networkError() };
|
|
@@ -406,12 +410,12 @@ function messageOf(error) {
|
|
|
406
410
|
return error instanceof Error ? error.message : "Network request failed.";
|
|
407
411
|
}
|
|
408
412
|
var warnedAboutKey = false;
|
|
409
|
-
function warnAboutKey(
|
|
410
|
-
if (code !== "invalid_key" || warnedAboutKey) return;
|
|
413
|
+
function warnAboutKey(error) {
|
|
414
|
+
if (error.code !== "invalid_key" || warnedAboutKey) return;
|
|
411
415
|
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
|
|
412
416
|
warnedAboutKey = true;
|
|
413
417
|
console.error(
|
|
414
|
-
"[fewchurs] The API key was rejected. Check FEWCHURS_API_KEY (server) or the apiKey passed to FewchursProvider, and that the key is active in your Fewchurs dashboard."
|
|
418
|
+
error.status === 403 ? `[fewchurs] ${error.message}` : "[fewchurs] The API key was rejected. Check FEWCHURS_API_KEY (server) or the apiKey passed to FewchursProvider, and that the key is active in your Fewchurs dashboard."
|
|
415
419
|
);
|
|
416
420
|
}
|
|
417
421
|
|
|
@@ -1726,6 +1730,7 @@ function FewchursBoardDialog({
|
|
|
1726
1730
|
open,
|
|
1727
1731
|
onClose,
|
|
1728
1732
|
ariaLabel = "Feature requests",
|
|
1733
|
+
variant = "dialog",
|
|
1729
1734
|
...boardProps
|
|
1730
1735
|
}) {
|
|
1731
1736
|
const dialogRef = (0, import_react16.useRef)(null);
|
|
@@ -1744,11 +1749,14 @@ function FewchursBoardDialog({
|
|
|
1744
1749
|
};
|
|
1745
1750
|
}, [open, onClose]);
|
|
1746
1751
|
if (!open) return null;
|
|
1747
|
-
|
|
1752
|
+
const isSheet = variant === "sheet";
|
|
1753
|
+
const { colorScheme } = boardProps;
|
|
1754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: isSheet ? "fw-overlay fw-overlay--sheet" : "fw-overlay", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1748
1755
|
"div",
|
|
1749
1756
|
{
|
|
1750
1757
|
ref: dialogRef,
|
|
1751
|
-
className: "fw-dialog",
|
|
1758
|
+
className: isSheet ? "fw-dialog fw-dialog--sheet" : "fw-dialog",
|
|
1759
|
+
"data-theme": colorScheme === "system" ? void 0 : colorScheme,
|
|
1752
1760
|
role: "dialog",
|
|
1753
1761
|
"aria-modal": "true",
|
|
1754
1762
|
"aria-label": ariaLabel,
|
|
@@ -1761,6 +1769,49 @@ function FewchursBoardDialog({
|
|
|
1761
1769
|
}
|
|
1762
1770
|
) });
|
|
1763
1771
|
}
|
|
1772
|
+
|
|
1773
|
+
// src/components/BoardButton.tsx
|
|
1774
|
+
var import_react17 = require("react");
|
|
1775
|
+
var import_react_dom = require("react-dom");
|
|
1776
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1777
|
+
function FewchursButton({
|
|
1778
|
+
children = "Feedback",
|
|
1779
|
+
className,
|
|
1780
|
+
style,
|
|
1781
|
+
ariaLabel,
|
|
1782
|
+
...board
|
|
1783
|
+
}) {
|
|
1784
|
+
const [open, setOpen] = (0, import_react17.useState)(false);
|
|
1785
|
+
const close = (0, import_react17.useCallback)(() => setOpen(false), []);
|
|
1786
|
+
const classes = [board.unstyled ? "" : "fw-launcher", className].filter(Boolean).join(" ");
|
|
1787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1788
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1789
|
+
"button",
|
|
1790
|
+
{
|
|
1791
|
+
type: "button",
|
|
1792
|
+
className: classes || void 0,
|
|
1793
|
+
style: { ...themeToStyle(board.theme), ...style },
|
|
1794
|
+
"aria-haspopup": "dialog",
|
|
1795
|
+
"aria-expanded": open,
|
|
1796
|
+
onClick: () => setOpen(true),
|
|
1797
|
+
children
|
|
1798
|
+
}
|
|
1799
|
+
),
|
|
1800
|
+
open ? (0, import_react_dom.createPortal)(
|
|
1801
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1802
|
+
FewchursBoardDialog,
|
|
1803
|
+
{
|
|
1804
|
+
...board,
|
|
1805
|
+
variant: "sheet",
|
|
1806
|
+
ariaLabel,
|
|
1807
|
+
open: true,
|
|
1808
|
+
onClose: close
|
|
1809
|
+
}
|
|
1810
|
+
),
|
|
1811
|
+
document.body
|
|
1812
|
+
) : null
|
|
1813
|
+
] });
|
|
1814
|
+
}
|
|
1764
1815
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1765
1816
|
0 && (module.exports = {
|
|
1766
1817
|
BoardRoot,
|
|
@@ -1776,6 +1827,7 @@ function FewchursBoardDialog({
|
|
|
1776
1827
|
FeatureList,
|
|
1777
1828
|
FewchursBoard,
|
|
1778
1829
|
FewchursBoardDialog,
|
|
1830
|
+
FewchursButton,
|
|
1779
1831
|
FewchursProvider,
|
|
1780
1832
|
FollowForm,
|
|
1781
1833
|
LIMITS,
|