@mzebley/mark-down-react 1.2.2 → 1.2.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/README.md +18 -16
- package/dist/index.cjs +21 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +21 -3
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# mark↓ React Adapter
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
_(published as `@mzebley/mark-down-react`)_
|
|
3
4
|
|
|
4
5
|
React bindings for the [mark↓ core runtime](../core/README.md). This package exposes context providers, hooks, and ready-to-use components that make it simple to render Markdown snippets safely. For a broader overview of the project, start with the [root README](../../README.md).
|
|
5
6
|
|
|
@@ -29,11 +30,11 @@ Generate a manifest with the [CLI](../cli/README.md) before rendering snippets.
|
|
|
29
30
|
Wrap your app with the `SnippetProvider` so that hooks and components can access a shared client instance:
|
|
30
31
|
|
|
31
32
|
```tsx
|
|
32
|
-
import { SnippetProvider } from
|
|
33
|
+
import { SnippetProvider } from "@mzebley/mark-down-react";
|
|
33
34
|
|
|
34
35
|
export function App({ children }: { children: React.ReactNode }) {
|
|
35
36
|
return (
|
|
36
|
-
<SnippetProvider options={{ manifest:
|
|
37
|
+
<SnippetProvider options={{ manifest: "/snippets-index.json" }}>
|
|
37
38
|
{children}
|
|
38
39
|
</SnippetProvider>
|
|
39
40
|
);
|
|
@@ -49,10 +50,10 @@ export function App({ children }: { children: React.ReactNode }) {
|
|
|
49
50
|
Fetch a single snippet and track loading / error state:
|
|
50
51
|
|
|
51
52
|
```tsx
|
|
52
|
-
import { useSnippet } from
|
|
53
|
+
import { useSnippet } from "@mzebley/mark-down-react";
|
|
53
54
|
|
|
54
55
|
export function Hero() {
|
|
55
|
-
const { snippet, loading, error } = useSnippet(
|
|
56
|
+
const { snippet, loading, error } = useSnippet("getting-started-welcome");
|
|
56
57
|
|
|
57
58
|
if (loading) return <p>Loading…</p>;
|
|
58
59
|
if (error) return <p role="alert">Failed to load snippet.</p>;
|
|
@@ -67,13 +68,13 @@ export function Hero() {
|
|
|
67
68
|
Render snippets declaratively with built-in loading and error fallbacks:
|
|
68
69
|
|
|
69
70
|
```tsx
|
|
70
|
-
import { SnippetView } from
|
|
71
|
+
import { SnippetView } from "@mzebley/mark-down-react";
|
|
71
72
|
|
|
72
73
|
<SnippetView
|
|
73
74
|
slug="components-button"
|
|
74
75
|
loadingFallback={<p>Loading…</p>}
|
|
75
76
|
errorFallback={<p role="alert">Unable to load snippet.</p>}
|
|
76
|
-
onLoaded={(snippet) => console.log(
|
|
77
|
+
onLoaded={(snippet) => console.log("Rendered", snippet.slug)}
|
|
77
78
|
/>;
|
|
78
79
|
```
|
|
79
80
|
|
|
@@ -88,18 +89,19 @@ Features:
|
|
|
88
89
|
When using Next.js, Remix, or another SSR framework, provide a server-safe fetch implementation:
|
|
89
90
|
|
|
90
91
|
```tsx
|
|
91
|
-
import fetch from
|
|
92
|
-
import { SnippetProvider } from
|
|
92
|
+
import fetch from "node-fetch";
|
|
93
|
+
import { SnippetProvider } from "@mzebley/mark-down-react";
|
|
93
94
|
|
|
94
95
|
<SnippetProvider
|
|
95
96
|
options={{
|
|
96
|
-
manifest: () => import(
|
|
97
|
-
fetch: (url) =>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
97
|
+
manifest: () => import("../snippets-index.json"),
|
|
98
|
+
fetch: (url) =>
|
|
99
|
+
fetch(url).then((response) => {
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`Request failed with status ${response.status}`);
|
|
102
|
+
}
|
|
103
|
+
return response;
|
|
104
|
+
}),
|
|
103
105
|
}}
|
|
104
106
|
>
|
|
105
107
|
{children}
|
package/dist/index.cjs
CHANGED
|
@@ -42,7 +42,11 @@ var import_react = require("react");
|
|
|
42
42
|
var import_mark_down = require("@mzebley/mark-down");
|
|
43
43
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
44
44
|
var SnippetClientContext = (0, import_react.createContext)(null);
|
|
45
|
-
function SnippetProvider({
|
|
45
|
+
function SnippetProvider({
|
|
46
|
+
client,
|
|
47
|
+
options,
|
|
48
|
+
children
|
|
49
|
+
}) {
|
|
46
50
|
const value = (0, import_react.useMemo)(() => {
|
|
47
51
|
if (client) {
|
|
48
52
|
return client;
|
|
@@ -102,7 +106,15 @@ function SnippetView({
|
|
|
102
106
|
onLoaded
|
|
103
107
|
}) {
|
|
104
108
|
const state = useSnippet(slug);
|
|
105
|
-
const safeHtml = (0, import_react3.useMemo)(() =>
|
|
109
|
+
const safeHtml = (0, import_react3.useMemo)(() => {
|
|
110
|
+
if (!state.snippet) {
|
|
111
|
+
return void 0;
|
|
112
|
+
}
|
|
113
|
+
if (typeof window === "undefined") {
|
|
114
|
+
return state.snippet.html;
|
|
115
|
+
}
|
|
116
|
+
return import_dompurify.default.sanitize(state.snippet.html);
|
|
117
|
+
}, [state.snippet]);
|
|
106
118
|
(0, import_react3.useEffect)(() => {
|
|
107
119
|
onLoaded?.(state.snippet);
|
|
108
120
|
}, [state.snippet, onLoaded]);
|
|
@@ -115,7 +127,13 @@ function SnippetView({
|
|
|
115
127
|
if (!state.snippet) {
|
|
116
128
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className, children: "Snippet not found" });
|
|
117
129
|
}
|
|
118
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
130
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
131
|
+
"div",
|
|
132
|
+
{
|
|
133
|
+
className,
|
|
134
|
+
dangerouslySetInnerHTML: { __html: safeHtml ?? "" }
|
|
135
|
+
}
|
|
136
|
+
);
|
|
119
137
|
}
|
|
120
138
|
// Annotate the CommonJS export names for ESM import in node:
|
|
121
139
|
0 && (module.exports = {
|
package/dist/index.d.cts
CHANGED
|
@@ -7,7 +7,7 @@ interface SnippetProviderProps {
|
|
|
7
7
|
options?: SnippetClientOptions;
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
declare function SnippetProvider({ client, options, children }: SnippetProviderProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function SnippetProvider({ client, options, children, }: SnippetProviderProps): react_jsx_runtime.JSX.Element;
|
|
11
11
|
declare function useSnippetClient(): SnippetClient;
|
|
12
12
|
|
|
13
13
|
interface UseSnippetResult {
|
|
@@ -24,6 +24,6 @@ interface SnippetViewProps {
|
|
|
24
24
|
errorFallback?: ReactNode;
|
|
25
25
|
onLoaded?: (snippet?: Snippet) => void;
|
|
26
26
|
}
|
|
27
|
-
declare function SnippetView({ slug, className, loadingFallback, errorFallback, onLoaded }: SnippetViewProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function SnippetView({ slug, className, loadingFallback, errorFallback, onLoaded, }: SnippetViewProps): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
29
|
export { SnippetProvider, type SnippetProviderProps, SnippetView, type SnippetViewProps, type UseSnippetResult, useSnippet, useSnippetClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ interface SnippetProviderProps {
|
|
|
7
7
|
options?: SnippetClientOptions;
|
|
8
8
|
children: ReactNode;
|
|
9
9
|
}
|
|
10
|
-
declare function SnippetProvider({ client, options, children }: SnippetProviderProps): react_jsx_runtime.JSX.Element;
|
|
10
|
+
declare function SnippetProvider({ client, options, children, }: SnippetProviderProps): react_jsx_runtime.JSX.Element;
|
|
11
11
|
declare function useSnippetClient(): SnippetClient;
|
|
12
12
|
|
|
13
13
|
interface UseSnippetResult {
|
|
@@ -24,6 +24,6 @@ interface SnippetViewProps {
|
|
|
24
24
|
errorFallback?: ReactNode;
|
|
25
25
|
onLoaded?: (snippet?: Snippet) => void;
|
|
26
26
|
}
|
|
27
|
-
declare function SnippetView({ slug, className, loadingFallback, errorFallback, onLoaded }: SnippetViewProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function SnippetView({ slug, className, loadingFallback, errorFallback, onLoaded, }: SnippetViewProps): react_jsx_runtime.JSX.Element;
|
|
28
28
|
|
|
29
29
|
export { SnippetProvider, type SnippetProviderProps, SnippetView, type SnippetViewProps, type UseSnippetResult, useSnippet, useSnippetClient };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,11 @@ import { createContext, useContext, useMemo } from "react";
|
|
|
3
3
|
import { SnippetClient } from "@mzebley/mark-down";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
var SnippetClientContext = createContext(null);
|
|
6
|
-
function SnippetProvider({
|
|
6
|
+
function SnippetProvider({
|
|
7
|
+
client,
|
|
8
|
+
options,
|
|
9
|
+
children
|
|
10
|
+
}) {
|
|
7
11
|
const value = useMemo(() => {
|
|
8
12
|
if (client) {
|
|
9
13
|
return client;
|
|
@@ -63,7 +67,15 @@ function SnippetView({
|
|
|
63
67
|
onLoaded
|
|
64
68
|
}) {
|
|
65
69
|
const state = useSnippet(slug);
|
|
66
|
-
const safeHtml = useMemo2(() =>
|
|
70
|
+
const safeHtml = useMemo2(() => {
|
|
71
|
+
if (!state.snippet) {
|
|
72
|
+
return void 0;
|
|
73
|
+
}
|
|
74
|
+
if (typeof window === "undefined") {
|
|
75
|
+
return state.snippet.html;
|
|
76
|
+
}
|
|
77
|
+
return DOMPurify.sanitize(state.snippet.html);
|
|
78
|
+
}, [state.snippet]);
|
|
67
79
|
useEffect2(() => {
|
|
68
80
|
onLoaded?.(state.snippet);
|
|
69
81
|
}, [state.snippet, onLoaded]);
|
|
@@ -76,7 +88,13 @@ function SnippetView({
|
|
|
76
88
|
if (!state.snippet) {
|
|
77
89
|
return /* @__PURE__ */ jsx2("div", { className, children: "Snippet not found" });
|
|
78
90
|
}
|
|
79
|
-
return /* @__PURE__ */ jsx2(
|
|
91
|
+
return /* @__PURE__ */ jsx2(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
className,
|
|
95
|
+
dangerouslySetInnerHTML: { __html: safeHtml ?? "" }
|
|
96
|
+
}
|
|
97
|
+
);
|
|
80
98
|
}
|
|
81
99
|
export {
|
|
82
100
|
SnippetProvider,
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mzebley/mark-down-react",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "mark↓ React Adapter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
|
-
"files": [
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
10
12
|
"publishConfig": {
|
|
11
13
|
"access": "public"
|
|
12
14
|
},
|