@reapi/docs-ui 0.1.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/dist/index.d.ts +83 -0
- package/dist/index.js +350 -0
- package/package.json +44 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { Root } from 'mdast';
|
|
4
|
+
|
|
5
|
+
type DocsComponent = (props: any) => ReactNode;
|
|
6
|
+
declare const defaultComponents: Record<string, DocsComponent>;
|
|
7
|
+
declare function MdxContent({ ast, components, }: {
|
|
8
|
+
ast: Root;
|
|
9
|
+
components?: Record<string, DocsComponent>;
|
|
10
|
+
}): react.JSX.Element;
|
|
11
|
+
|
|
12
|
+
type AnyRecord = Record<string, unknown>;
|
|
13
|
+
declare function DocsEmbedProvider({ specs, children, }: {
|
|
14
|
+
specs: Record<string, AnyRecord>;
|
|
15
|
+
children?: ReactNode;
|
|
16
|
+
}): react.JSX.Element;
|
|
17
|
+
/** `<ApiOperation api="petstore" operation="GET /pets" />` */
|
|
18
|
+
declare function ApiOperation({ api, operation }: {
|
|
19
|
+
api?: string;
|
|
20
|
+
operation?: string;
|
|
21
|
+
}): react.JSX.Element;
|
|
22
|
+
/** `<ApiSchema api="petstore" name="Pet" />` */
|
|
23
|
+
declare function ApiSchema({ api, name }: {
|
|
24
|
+
api?: string;
|
|
25
|
+
name?: string;
|
|
26
|
+
}): react.JSX.Element;
|
|
27
|
+
|
|
28
|
+
declare const Note: (p: {
|
|
29
|
+
title?: string;
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
}) => react.JSX.Element;
|
|
32
|
+
declare const Warning: (p: {
|
|
33
|
+
title?: string;
|
|
34
|
+
children?: ReactNode;
|
|
35
|
+
}) => react.JSX.Element;
|
|
36
|
+
declare const Tip: (p: {
|
|
37
|
+
title?: string;
|
|
38
|
+
children?: ReactNode;
|
|
39
|
+
}) => react.JSX.Element;
|
|
40
|
+
|
|
41
|
+
declare function Tab({ children }: {
|
|
42
|
+
title?: string;
|
|
43
|
+
children?: ReactNode;
|
|
44
|
+
}): react.JSX.Element;
|
|
45
|
+
/** `<Tabs><Tab title="npm">…</Tab><Tab title="pnpm">…</Tab></Tabs>` */
|
|
46
|
+
declare function Tabs({ children }: {
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
}): react.JSX.Element | null;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* `<CodeGroup>` with fenced code blocks as children — each block's
|
|
52
|
+
* ```lang title meta becomes the tab label (falling back to the language).
|
|
53
|
+
*/
|
|
54
|
+
declare function CodeGroup({ children }: {
|
|
55
|
+
children?: ReactNode;
|
|
56
|
+
}): react.JSX.Element | null;
|
|
57
|
+
|
|
58
|
+
declare function Card({ title, href, children, }: {
|
|
59
|
+
title?: string;
|
|
60
|
+
href?: string;
|
|
61
|
+
children?: ReactNode;
|
|
62
|
+
}): react.JSX.Element;
|
|
63
|
+
declare function CardGroup({ cols, children }: {
|
|
64
|
+
cols?: string;
|
|
65
|
+
children?: ReactNode;
|
|
66
|
+
}): react.JSX.Element;
|
|
67
|
+
|
|
68
|
+
/** Native <details> — interactive without any client JS (RSC-friendly). */
|
|
69
|
+
declare function Accordion({ title, children }: {
|
|
70
|
+
title?: string;
|
|
71
|
+
children?: ReactNode;
|
|
72
|
+
}): react.JSX.Element;
|
|
73
|
+
declare function AccordionGroup({ children }: {
|
|
74
|
+
children?: ReactNode;
|
|
75
|
+
}): react.JSX.Element;
|
|
76
|
+
|
|
77
|
+
/** A captioned figure wrapper (images, screenshots). */
|
|
78
|
+
declare function Frame({ caption, children }: {
|
|
79
|
+
caption?: string;
|
|
80
|
+
children?: ReactNode;
|
|
81
|
+
}): react.JSX.Element;
|
|
82
|
+
|
|
83
|
+
export { Accordion, AccordionGroup, ApiOperation, ApiSchema, Card, CardGroup, CodeGroup, type DocsComponent, DocsEmbedProvider, Frame, MdxContent, Note, Tab, Tabs, Tip, Warning, defaultComponents };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
// src/renderer.tsx
|
|
2
|
+
import { Fragment as Fragment2, createElement } from "react";
|
|
3
|
+
|
|
4
|
+
// src/components/callout.tsx
|
|
5
|
+
import { Info, AlertTriangle, Lightbulb } from "lucide-react";
|
|
6
|
+
import { cn } from "@reapi/spec-ui";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
var VARIANTS = {
|
|
9
|
+
note: {
|
|
10
|
+
icon: Info,
|
|
11
|
+
classes: "border-sky-200 bg-sky-50 text-sky-900 dark:border-sky-900 dark:bg-sky-950 dark:text-sky-200"
|
|
12
|
+
},
|
|
13
|
+
warning: {
|
|
14
|
+
icon: AlertTriangle,
|
|
15
|
+
classes: "border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-900 dark:bg-amber-950 dark:text-amber-200"
|
|
16
|
+
},
|
|
17
|
+
tip: {
|
|
18
|
+
icon: Lightbulb,
|
|
19
|
+
classes: "border-emerald-200 bg-emerald-50 text-emerald-900 dark:border-emerald-900 dark:bg-emerald-950 dark:text-emerald-200"
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function Callout({
|
|
23
|
+
variant,
|
|
24
|
+
title,
|
|
25
|
+
children
|
|
26
|
+
}) {
|
|
27
|
+
const { icon: Icon, classes } = VARIANTS[variant];
|
|
28
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("not-prose my-4 flex gap-2.5 rounded-lg border p-3 text-sm", classes), children: [
|
|
29
|
+
/* @__PURE__ */ jsx(Icon, { className: "mt-0.5 size-4 shrink-0" }),
|
|
30
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 [&>p]:my-0 [&>p+p]:mt-2", children: [
|
|
31
|
+
title && /* @__PURE__ */ jsx("p", { className: "mb-1 font-semibold", children: title }),
|
|
32
|
+
children
|
|
33
|
+
] })
|
|
34
|
+
] });
|
|
35
|
+
}
|
|
36
|
+
var Note = (p) => /* @__PURE__ */ jsx(Callout, { variant: "note", ...p });
|
|
37
|
+
var Warning = (p) => /* @__PURE__ */ jsx(Callout, { variant: "warning", ...p });
|
|
38
|
+
var Tip = (p) => /* @__PURE__ */ jsx(Callout, { variant: "tip", ...p });
|
|
39
|
+
|
|
40
|
+
// src/components/tabs.tsx
|
|
41
|
+
import { Children, isValidElement, useState } from "react";
|
|
42
|
+
import { cn as cn2 } from "@reapi/spec-ui";
|
|
43
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
44
|
+
function Tab({ children }) {
|
|
45
|
+
return /* @__PURE__ */ jsx2("div", { children });
|
|
46
|
+
}
|
|
47
|
+
function Tabs({ children }) {
|
|
48
|
+
const items = Children.toArray(children).filter(
|
|
49
|
+
(c) => isValidElement(c) && c.type === Tab
|
|
50
|
+
);
|
|
51
|
+
const [active, setActive] = useState(0);
|
|
52
|
+
if (!items.length) return null;
|
|
53
|
+
return /* @__PURE__ */ jsxs2("div", { className: "not-prose my-4 rounded-lg border", children: [
|
|
54
|
+
/* @__PURE__ */ jsx2("div", { className: "flex gap-1 border-b bg-muted/40 px-2 pt-1.5", children: items.map((item, i) => /* @__PURE__ */ jsx2(
|
|
55
|
+
"button",
|
|
56
|
+
{
|
|
57
|
+
type: "button",
|
|
58
|
+
onClick: () => setActive(i),
|
|
59
|
+
className: cn2(
|
|
60
|
+
"-mb-px rounded-t-md border-x border-t px-3 py-1.5 text-xs font-medium",
|
|
61
|
+
i === active ? "border-border bg-background" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
62
|
+
),
|
|
63
|
+
children: item.props.title ?? `Tab ${i + 1}`
|
|
64
|
+
},
|
|
65
|
+
i
|
|
66
|
+
)) }),
|
|
67
|
+
/* @__PURE__ */ jsx2("div", { className: "p-3 text-sm [&>p]:my-0 [&>p+p]:mt-2", children: items[active] })
|
|
68
|
+
] });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/components/code-group.tsx
|
|
72
|
+
import { Children as Children2, isValidElement as isValidElement2, useState as useState2 } from "react";
|
|
73
|
+
import { cn as cn3 } from "@reapi/spec-ui";
|
|
74
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
75
|
+
function CodeGroup({ children }) {
|
|
76
|
+
const blocks = Children2.toArray(children).filter(isValidElement2);
|
|
77
|
+
const [active, setActive] = useState2(0);
|
|
78
|
+
if (!blocks.length) return null;
|
|
79
|
+
const label = (el, i) => {
|
|
80
|
+
const props = el.props;
|
|
81
|
+
return props["data-title"] ?? props["data-language"] ?? `Code ${i + 1}`;
|
|
82
|
+
};
|
|
83
|
+
return /* @__PURE__ */ jsxs3("div", { className: "not-prose my-4 overflow-hidden rounded-lg border bg-muted/30", children: [
|
|
84
|
+
/* @__PURE__ */ jsx3("div", { className: "flex gap-1 border-b bg-muted/60 px-2 pt-1.5", children: blocks.map((b, i) => /* @__PURE__ */ jsx3(
|
|
85
|
+
"button",
|
|
86
|
+
{
|
|
87
|
+
type: "button",
|
|
88
|
+
onClick: () => setActive(i),
|
|
89
|
+
className: cn3(
|
|
90
|
+
"-mb-px rounded-t-md px-3 py-1.5 font-mono text-[11px] font-medium",
|
|
91
|
+
i === active ? "bg-background" : "text-muted-foreground hover:text-foreground"
|
|
92
|
+
),
|
|
93
|
+
children: label(b, i)
|
|
94
|
+
},
|
|
95
|
+
i
|
|
96
|
+
)) }),
|
|
97
|
+
/* @__PURE__ */ jsx3("div", { className: "[&_pre]:my-0 [&_pre]:rounded-none [&_pre]:border-0", children: blocks[active] })
|
|
98
|
+
] });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/components/card.tsx
|
|
102
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
103
|
+
function Card({
|
|
104
|
+
title,
|
|
105
|
+
href,
|
|
106
|
+
children
|
|
107
|
+
}) {
|
|
108
|
+
const body = /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
109
|
+
title && /* @__PURE__ */ jsx4("p", { className: "mb-1 text-sm font-semibold", children: title }),
|
|
110
|
+
/* @__PURE__ */ jsx4("div", { className: "text-sm text-muted-foreground [&>p]:my-0 [&>p+p]:mt-2", children })
|
|
111
|
+
] });
|
|
112
|
+
const classes = "not-prose block rounded-lg border p-4";
|
|
113
|
+
return href ? /* @__PURE__ */ jsx4("a", { href, className: `${classes} transition-colors hover:bg-accent`, children: body }) : /* @__PURE__ */ jsx4("div", { className: classes, children: body });
|
|
114
|
+
}
|
|
115
|
+
function CardGroup({ cols, children }) {
|
|
116
|
+
const n = Math.min(Math.max(Number(cols) || 2, 1), 4);
|
|
117
|
+
return /* @__PURE__ */ jsx4(
|
|
118
|
+
"div",
|
|
119
|
+
{
|
|
120
|
+
className: "not-prose my-4 grid gap-3",
|
|
121
|
+
style: { gridTemplateColumns: `repeat(${n}, minmax(0, 1fr))` },
|
|
122
|
+
children
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/components/accordion.tsx
|
|
128
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
129
|
+
function Accordion({ title, children }) {
|
|
130
|
+
return /* @__PURE__ */ jsxs5("details", { className: "not-prose group my-2 rounded-lg border", children: [
|
|
131
|
+
/* @__PURE__ */ jsx5("summary", { className: "cursor-pointer select-none px-4 py-2.5 text-sm font-medium marker:text-muted-foreground", children: title ?? "Details" }),
|
|
132
|
+
/* @__PURE__ */ jsx5("div", { className: "border-t px-4 py-3 text-sm [&>p]:my-0 [&>p+p]:mt-2", children })
|
|
133
|
+
] });
|
|
134
|
+
}
|
|
135
|
+
function AccordionGroup({ children }) {
|
|
136
|
+
return /* @__PURE__ */ jsx5("div", { className: "not-prose my-4 [&>details]:my-0 [&>details+details]:-mt-px [&>details]:rounded-none [&>details:first-child]:rounded-t-lg [&>details:last-child]:rounded-b-lg", children });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/components/frame.tsx
|
|
140
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
141
|
+
function Frame({ caption, children }) {
|
|
142
|
+
return /* @__PURE__ */ jsxs6("figure", { className: "not-prose my-4 overflow-hidden rounded-lg border", children: [
|
|
143
|
+
/* @__PURE__ */ jsx6("div", { className: "flex justify-center bg-muted/30 p-3 [&_img]:rounded-md", children }),
|
|
144
|
+
caption && /* @__PURE__ */ jsx6("figcaption", { className: "border-t px-3 py-1.5 text-center text-xs text-muted-foreground", children: caption })
|
|
145
|
+
] });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/components/api-embeds.tsx
|
|
149
|
+
import { createContext, useContext } from "react";
|
|
150
|
+
import {
|
|
151
|
+
ConstraintPills,
|
|
152
|
+
Markdown,
|
|
153
|
+
OperationSection,
|
|
154
|
+
SchemaFields,
|
|
155
|
+
createRefResolver,
|
|
156
|
+
isRef
|
|
157
|
+
} from "@reapi/spec-ui";
|
|
158
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
159
|
+
var EmbedSpecsContext = createContext({});
|
|
160
|
+
function DocsEmbedProvider({
|
|
161
|
+
specs,
|
|
162
|
+
children
|
|
163
|
+
}) {
|
|
164
|
+
return /* @__PURE__ */ jsx7(EmbedSpecsContext.Provider, { value: specs, children });
|
|
165
|
+
}
|
|
166
|
+
function MissingEmbed({ children }) {
|
|
167
|
+
return /* @__PURE__ */ jsx7("div", { className: "not-prose my-4 rounded-lg border border-dashed px-4 py-3 text-sm text-muted-foreground", children });
|
|
168
|
+
}
|
|
169
|
+
function ApiOperation({ api, operation }) {
|
|
170
|
+
const specs = useContext(EmbedSpecsContext);
|
|
171
|
+
const spec = api ? specs[api] : void 0;
|
|
172
|
+
const parts = (operation ?? "").trim().split(/\s+/);
|
|
173
|
+
if (!api || parts.length !== 2) {
|
|
174
|
+
return /* @__PURE__ */ jsx7(MissingEmbed, { children: '<ApiOperation> needs api="\u2026" and operation="GET /path"' });
|
|
175
|
+
}
|
|
176
|
+
if (!spec) {
|
|
177
|
+
return /* @__PURE__ */ jsx7(MissingEmbed, { children: `API "${api}" is not published \u2014 publish it to render this embed.` });
|
|
178
|
+
}
|
|
179
|
+
const [method, path] = parts;
|
|
180
|
+
const op = spec.paths?.[path]?.[method.toLowerCase()];
|
|
181
|
+
if (!op) {
|
|
182
|
+
return /* @__PURE__ */ jsx7(MissingEmbed, { children: `Operation ${method.toUpperCase()} ${path} not found in "${api}".` });
|
|
183
|
+
}
|
|
184
|
+
return /* @__PURE__ */ jsx7("div", { className: "not-prose my-4 rounded-lg border px-5 [&>section]:border-t-0 [&>section]:py-5", children: /* @__PURE__ */ jsx7(
|
|
185
|
+
OperationSection,
|
|
186
|
+
{
|
|
187
|
+
spec,
|
|
188
|
+
id: `embed-${method}-${path}`.replace(/[^a-zA-Z0-9-]+/g, "-"),
|
|
189
|
+
method: method.toUpperCase(),
|
|
190
|
+
path,
|
|
191
|
+
resolve: createRefResolver(spec, null)
|
|
192
|
+
}
|
|
193
|
+
) });
|
|
194
|
+
}
|
|
195
|
+
function ApiSchema({ api, name }) {
|
|
196
|
+
const specs = useContext(EmbedSpecsContext);
|
|
197
|
+
const spec = api ? specs[api] : void 0;
|
|
198
|
+
if (!api || !name) {
|
|
199
|
+
return /* @__PURE__ */ jsx7(MissingEmbed, { children: '<ApiSchema> needs api="\u2026" and name="\u2026"' });
|
|
200
|
+
}
|
|
201
|
+
if (!spec) {
|
|
202
|
+
return /* @__PURE__ */ jsx7(MissingEmbed, { children: `API "${api}" is not published \u2014 publish it to render this embed.` });
|
|
203
|
+
}
|
|
204
|
+
const schema = (spec.components?.schemas ?? {})[name];
|
|
205
|
+
if (!schema) {
|
|
206
|
+
return /* @__PURE__ */ jsx7(MissingEmbed, { children: `Schema "${name}" not found in "${api}".` });
|
|
207
|
+
}
|
|
208
|
+
return /* @__PURE__ */ jsxs7("div", { className: "not-prose my-4 rounded-lg border px-4 py-3", children: [
|
|
209
|
+
/* @__PURE__ */ jsx7("p", { className: "font-mono text-sm font-semibold", children: name }),
|
|
210
|
+
!isRef(schema) && typeof schema.description === "string" && schema.description && /* @__PURE__ */ jsx7(Markdown, { compact: true, children: schema.description }),
|
|
211
|
+
/* @__PURE__ */ jsx7(ConstraintPills, { schema }),
|
|
212
|
+
/* @__PURE__ */ jsx7("div", { className: "mt-1", children: /* @__PURE__ */ jsx7(SchemaFields, { schema, resolve: createRefResolver(spec, null) }) })
|
|
213
|
+
] });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/renderer.tsx
|
|
217
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
218
|
+
var defaultComponents = {
|
|
219
|
+
Note,
|
|
220
|
+
Warning,
|
|
221
|
+
Tip,
|
|
222
|
+
Tabs,
|
|
223
|
+
Tab,
|
|
224
|
+
CodeGroup,
|
|
225
|
+
Card,
|
|
226
|
+
CardGroup,
|
|
227
|
+
Accordion,
|
|
228
|
+
AccordionGroup,
|
|
229
|
+
Frame,
|
|
230
|
+
ApiOperation,
|
|
231
|
+
ApiSchema
|
|
232
|
+
};
|
|
233
|
+
function jsxProps(node) {
|
|
234
|
+
const out = {};
|
|
235
|
+
for (const attr of node.attributes ?? []) {
|
|
236
|
+
if (attr.type !== "mdxJsxAttribute" || typeof attr.name !== "string") continue;
|
|
237
|
+
out[attr.name] = attr.value === null || attr.value === void 0 ? true : attr.value;
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
function render(node, key, components) {
|
|
242
|
+
const kids = (extra) => (extra ?? node.children ?? []).map((c, i) => render(c, i, components));
|
|
243
|
+
switch (node.type) {
|
|
244
|
+
case "root":
|
|
245
|
+
return /* @__PURE__ */ jsx8(Fragment2, { children: kids() }, key);
|
|
246
|
+
case "text":
|
|
247
|
+
return node.value ?? "";
|
|
248
|
+
case "paragraph":
|
|
249
|
+
return /* @__PURE__ */ jsx8("p", { children: kids() }, key);
|
|
250
|
+
case "heading": {
|
|
251
|
+
const depth = Math.min(Math.max(Number(node.depth) || 2, 1), 6);
|
|
252
|
+
const id = node.data?.id;
|
|
253
|
+
return createElement(`h${depth}`, { key, id, className: "scroll-mt-20" }, kids());
|
|
254
|
+
}
|
|
255
|
+
case "emphasis":
|
|
256
|
+
return /* @__PURE__ */ jsx8("em", { children: kids() }, key);
|
|
257
|
+
case "strong":
|
|
258
|
+
return /* @__PURE__ */ jsx8("strong", { children: kids() }, key);
|
|
259
|
+
case "delete":
|
|
260
|
+
return /* @__PURE__ */ jsx8("del", { children: kids() }, key);
|
|
261
|
+
case "inlineCode":
|
|
262
|
+
return /* @__PURE__ */ jsx8("code", { children: node.value ?? "" }, key);
|
|
263
|
+
case "code": {
|
|
264
|
+
const lang = typeof node.lang === "string" ? node.lang : void 0;
|
|
265
|
+
const meta = typeof node.meta === "string" ? node.meta.trim() : void 0;
|
|
266
|
+
return /* @__PURE__ */ jsx8("pre", { "data-language": lang, "data-title": meta || void 0, children: /* @__PURE__ */ jsx8("code", { className: lang ? `language-${lang}` : void 0, children: node.value ?? "" }) }, key);
|
|
267
|
+
}
|
|
268
|
+
case "blockquote":
|
|
269
|
+
return /* @__PURE__ */ jsx8("blockquote", { children: kids() }, key);
|
|
270
|
+
case "list":
|
|
271
|
+
return node.ordered ? /* @__PURE__ */ jsx8("ol", { start: typeof node.start === "number" ? node.start : void 0, children: kids() }, key) : /* @__PURE__ */ jsx8("ul", { children: kids() }, key);
|
|
272
|
+
case "listItem": {
|
|
273
|
+
const checked = node.checked;
|
|
274
|
+
const children = node.spread === true ? node.children ?? [] : (node.children ?? []).flatMap((c) => c.type === "paragraph" ? c.children ?? [] : [c]);
|
|
275
|
+
return /* @__PURE__ */ jsxs8("li", { className: checked != null ? "list-none" : void 0, children: [
|
|
276
|
+
checked != null && /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: checked === true, readOnly: true, className: "mr-1.5 align-middle" }),
|
|
277
|
+
kids(children)
|
|
278
|
+
] }, key);
|
|
279
|
+
}
|
|
280
|
+
case "thematicBreak":
|
|
281
|
+
return /* @__PURE__ */ jsx8("hr", {}, key);
|
|
282
|
+
case "break":
|
|
283
|
+
return /* @__PURE__ */ jsx8("br", {}, key);
|
|
284
|
+
case "link": {
|
|
285
|
+
const href = typeof node.url === "string" ? node.url : "#";
|
|
286
|
+
const external = /^https?:\/\//.test(href);
|
|
287
|
+
return /* @__PURE__ */ jsx8("a", { href, target: external ? "_blank" : void 0, rel: external ? "noreferrer" : void 0, children: kids() }, key);
|
|
288
|
+
}
|
|
289
|
+
case "image":
|
|
290
|
+
return /* @__PURE__ */ jsx8(
|
|
291
|
+
"img",
|
|
292
|
+
{
|
|
293
|
+
src: typeof node.url === "string" ? node.url : void 0,
|
|
294
|
+
alt: typeof node.alt === "string" ? node.alt : "",
|
|
295
|
+
title: typeof node.title === "string" ? node.title : void 0
|
|
296
|
+
},
|
|
297
|
+
key
|
|
298
|
+
);
|
|
299
|
+
case "table": {
|
|
300
|
+
const rows = node.children ?? [];
|
|
301
|
+
const align = node.align ?? [];
|
|
302
|
+
const [head, ...body] = rows;
|
|
303
|
+
const renderRow = (row, ri, header) => /* @__PURE__ */ jsx8("tr", { children: (row.children ?? []).map(
|
|
304
|
+
(cell, ci) => createElement(
|
|
305
|
+
header ? "th" : "td",
|
|
306
|
+
{ key: ci, style: align[ci] ? { textAlign: align[ci] } : void 0 },
|
|
307
|
+
cell.children?.map((c, i) => render(c, i, components))
|
|
308
|
+
)
|
|
309
|
+
) }, ri);
|
|
310
|
+
return /* @__PURE__ */ jsxs8("table", { children: [
|
|
311
|
+
head && /* @__PURE__ */ jsx8("thead", { children: renderRow(head, 0, true) }),
|
|
312
|
+
/* @__PURE__ */ jsx8("tbody", { children: body.map((r, i) => renderRow(r, i, false)) })
|
|
313
|
+
] }, key);
|
|
314
|
+
}
|
|
315
|
+
case "mdxJsxFlowElement":
|
|
316
|
+
case "mdxJsxTextElement": {
|
|
317
|
+
const name = typeof node.name === "string" ? node.name : "";
|
|
318
|
+
const Component = components[name];
|
|
319
|
+
if (!Component) return /* @__PURE__ */ jsx8(Fragment2, { children: kids() }, key);
|
|
320
|
+
return /* @__PURE__ */ jsx8(Component, { ...jsxProps(node), children: node.children?.length ? kids() : void 0 }, key);
|
|
321
|
+
}
|
|
322
|
+
default:
|
|
323
|
+
return node.children ? /* @__PURE__ */ jsx8(Fragment2, { children: kids() }, key) : null;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function MdxContent({
|
|
327
|
+
ast,
|
|
328
|
+
components
|
|
329
|
+
}) {
|
|
330
|
+
const registry = components ? { ...defaultComponents, ...components } : defaultComponents;
|
|
331
|
+
return /* @__PURE__ */ jsx8(Fragment3, { children: render(ast, 0, registry) });
|
|
332
|
+
}
|
|
333
|
+
export {
|
|
334
|
+
Accordion,
|
|
335
|
+
AccordionGroup,
|
|
336
|
+
ApiOperation,
|
|
337
|
+
ApiSchema,
|
|
338
|
+
Card,
|
|
339
|
+
CardGroup,
|
|
340
|
+
CodeGroup,
|
|
341
|
+
DocsEmbedProvider,
|
|
342
|
+
Frame,
|
|
343
|
+
MdxContent,
|
|
344
|
+
Note,
|
|
345
|
+
Tab,
|
|
346
|
+
Tabs,
|
|
347
|
+
Tip,
|
|
348
|
+
Warning,
|
|
349
|
+
defaultComponents
|
|
350
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reapi/docs-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "AST→React renderer + preset components for the ReAPI docs dialect",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"lucide-react": "^0.469.0",
|
|
17
|
+
"@reapi/spec-ui": "0.1.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "^19.0.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/mdast": "^4.0.4",
|
|
24
|
+
"@types/react": "^19.0.0",
|
|
25
|
+
"@types/react-dom": "^19.0.0",
|
|
26
|
+
"react": "^19.1.0",
|
|
27
|
+
"react-dom": "^19.1.0",
|
|
28
|
+
"tsup": "^8.4.0",
|
|
29
|
+
"typescript": "^5.7.3",
|
|
30
|
+
"vitest": "^4.1.8",
|
|
31
|
+
"@reapi/docs-compile": "0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"test": "vitest --run",
|
|
42
|
+
"build": "tsup"
|
|
43
|
+
}
|
|
44
|
+
}
|